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"); }