/****************************************************************************/ /** **/ /** Hardlock Demo Program **/ /** **/ /** This demo program is based on the Hardlock application interface, **/ /** called API, to access a Hardlock via a local or a remote port. **/ /** To access the Hardlock remote, HL-Server must be installed first. **/ /** **/ /** ///FAST Software Security - Group Aladdin **/ /** **/ /** Computer: IBM PC or compatible **/ /** OS : MS-PC/DOS 2.0 or higher, OS/2, Windows NT **/ /** Language: 16/32 bit C (TURBO C, MSC, WATCOM) **/ /** **/ /** Note **/ /** ---- **/ /** The following demo program is not meant to represent a real good **/ /** implementation of software protection into your application. It **/ /** demonstrates the basic use of the Hardlock API functions and is **/ /** thus as short and simple as possible. Please read the manual **/ /** carefully to get an insight in the strategy of the implementation. **/ /** Please keep in mind that there is no general solution for a good **/ /** protection. We provide you with the necessary functions, the **/ /** implementation itself is up to you and your imagination. **/ /** **/ /** Revision history **/ /** ---------------- *** $Log: not supported by cvs2svn $ *** Revision 1.4 1999/12/15 09:52:54 chris *** don't print control chars *** *** *** Revision 1.3 1998/07/13 16:27:57 chris *** Added HL_READID call *** *** Revision 1.2 1997/02/14 11:14:28 chris *** added LM error messages *** *** Revision 1.1 1996/11/13 20:08:09 chris *** Initial revision **/ /****************************************************************************/ #include #include #include "hlapi_c.h" /* ------------------------------------------------------------------------ */ /* Module address of Hardlock test device and RefKey/VerKey. We generated */ /* the VerifyKey with TESTAPI.EXE. The API use the keys to identify the */ /* Hardlock with the correct encoding. */ /* The keys defined here are only valid for the demo module. */ /* You have to change module address AND VerKey for your specific Hardlock! */ /* ------------------------------------------------------------------------ */ #define MODAD 29809 Byte RefKey[8] = {'H','A','R','D','L','O','C','K'}; Byte VerKey[8] = {0x18,0x4C,0x97,0xF0,0xC0,0x7A,0x08,0x88}; /* ----------------------------------------- */ /* CryptStr contains the encrypted message : */ /* "The Answer to the Great Question" */ /* (only valid for the demo module). */ /* ----------------------------------------- */ Byte CryptStr[33] = {0x2D, 0xD4, 0x16, 0xA3, 0x19, 0x5C, 0xC2, 0x18, 0xAB, 0xA3, 0x8C, 0xDC, 0x8E, 0x66, 0xD4, 0xAB, 0x8F, 0xC0, 0x2F, 0x19, 0x39, 0xBA, 0x76, 0x5C, 0xE2, 0x06, 0x7C, 0x98, 0xC8, 0xA3, 0x55, 0x24, 0x00}; /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ int main(void) { char Text[33]; /* Temp. Var. */ Word n, Reg, Val; /* Counter, Register & Value */ Word TestOK; /* Return value from subroutines */ Byte Memory[128]; /* Save old Hardlock RAM & ROM */ Byte OldMem[128]; /* " " */ Byte NewRAM[33]; /* New Hardlock RAM */ Long SerialID = 0; /* Module internal serial ID */ printf("\n+---------------+"); printf("\n| Hardlock Demo |"); printf("\n+---------------+\n\n"); /* ------------------------------------- */ /* First we need to initialize the API : */ /* ------------------------------------- */ TestOK = HL_LOGIN(MODAD, DONT_CARE, RefKey, VerKey); if(TestOK != STATUS_OK) { switch (TestOK) { case NETWORK_ERROR: printf(" Sorry, a network error occured, maybe protocol (IPX/Netbios) not loaded!!\n\n"); break; case NO_DONGLE: printf(" Sorry, no Hardlock with this ID found!!\n\n"); break; case VERSION_MISMATCH: printf(" Sorry, version mismatch between API and HL-Server or device driver!!\n\n"); break; case TOO_MANY_USERS: printf(" Sorry, too many logins to HL-Server. Login table full!!\n\n"); break; case CANNOT_OPEN_DRIVER: printf(" Sorry, cannot open driver, maybe Hardlock driver not installed!!\n\n"); break; case INVALID_ENV: printf(" Sorry, invalid environment search string!! (HL_SEARCH)\n\n"); break; case INVALID_LIC: printf(" Sorry, no valid licence memory image found!! (LM)\n\n"); break; case NO_LICENSE: printf(" Sorry, no licence information for the requested slot!! (LM)\n\n"); break; default: printf(" Sorry, an unexpected error occured!! ERROR: %d\n\n", TestOK); break; } return (TestOK); } printf("\n Hardlock with Module address\t\t: %d\n", MODAD); /* ---------------------------- */ /* Get the API version number : */ /* ---------------------------- */ printf(" The API version is\t\t\t: %d\n",HL_VERSION()); /* ----------------------------------------------------- */ /* Looking for the Hardlock with the expected coding. */ /* ----------------------------------------------------- */ if(HL_AVAIL() == STATUS_OK) printf(" The connected Hardlock is\t\t: Test device\n"); else printf(" The connected Hardlock is\t\t: Not the test device\n"); /* ------------------------------------------------------------ */ /* Now we can get some informations about the connected module. */ /* ------------------------------------------------------------ */ TestOK = HL_ACCINF(); switch (TestOK) { case LOCAL_DEVICE: printf(" The Hardlock access is\t\t\t: Local\n"); printf(" Connected to the local port address\t: 0x%03X\n", HL_PORTINF()); break; case NET_DEVICE: printf(" The Hardlock access is\t\t\t: Remote\n"); printf(" The HL-Server version is\t\t: %d\n", HL_HLSVERS()); printf(" Connected to the remote port address\t: 0x%03X\n", HL_PORTINF()); printf(" Number of users logged in HL-Server is\t: %d\n", HL_USERINF()); printf(" The max. number of HL-Server logins is\t: %d\n", HL_MAXUSER()); break; default: printf(" The Hardlock access is\t\t: No access\n"); break; } /* ------------------------------------------------------ */ /* Read the internal serial number of Hardlock USB Module */ /* ------------------------------------------------------ */ TestOK = HL_READID((Word *)&SerialID, ((Word *)&SerialID)+1); switch (TestOK) { case STATUS_OK: printf(" The serial number ID is\t\t: %lu (0x%08lX)\n", SerialID, SerialID); break; case NO_SERIALID: printf(" The serial number ID is\t\t: not available for this Key\n"); break; default: printf(" Cannot determine serial ID, API error:\t: %i\n", TestOK); } /* ------------------------------------------------------ */ /* Now we decrypt the message from CryptStr. Maybe we use */ /* the message in our application. */ /* ------------------------------------------------------ */ printf("\n The encrypted message is\t\t: "); for (n = 0; n < 32; n++) printf("%c",(CryptStr[n] < 32 || CryptStr[n] > 126) ? '.' : CryptStr[n]); TestOK = HL_AVAIL(); if (TestOK == STATUS_OK) TestOK = HL_CODE(CryptStr, 4); if(TestOK == STATUS_OK) { /* ------------------------------------------------- */ /* HL_CODE returned 0, CryptStr should be decrypted. */ /* ------------------------------------------------- */ printf("\n The decrypted message is\t\t: "); for (n = 0; n < 32; n++) printf("%c",(CryptStr[n] < 32 || CryptStr[n] > 126) ? '.' : CryptStr[n]); HL_CODE(CryptStr, 4); printf("\n Encrypted again\t\t\t: "); for (n = 0; n < 32; n++) printf("%c",(CryptStr[n] < 32 || CryptStr[n] > 126) ? '.' : CryptStr[n]); } else /* ----------------------------------------------------------------------*/ /* HL_CODE returned an other value, maybe someone removed the Hardlock ? */ /* ----------------------------------------------------------------------*/ printf("\n Sorry, the decryption has failed!"); /* ---------------------------------------------------- */ /* We're looking for the memory option of the Hardlock. */ /* ---------------------------------------------------- */ TestOK = HL_MEMINF(); if(TestOK == STATUS_OK) { printf("\n\n Hardlock with memory\t\t\t: Yes\n"); /* ------------------------------------------------------- */ /* Now we can work with the memory. Let's read the string */ /* written in register 48 to 63. */ /* ------------------------------------------------------- */ for(n = 0, Reg = 48; Reg < 64; Reg++) { /* -------------------------------------------------------- */ /* The memory is organized as 16 bit registers, so we have */ /* to perform a typecasting. */ /* -------------------------------------------------------- */ HL_READ(Reg, &Val); Text[n++] = (char) (Val >> 8); Text[n++] = (char) (Val & 255); } /* ---------------------------------- */ /* We terminate the string with 0 ... */ /* ---------------------------------- */ Text[n] = '\0'; /* ----------------- */ /* ... and print it. */ /* ----------------- */ printf(" Read all registers of RAM area (Intel)\t: ["); for (n = 0; n < 32; n++) printf("%c", ((unsigned char) Text[n] < 32 || (unsigned char) Text[n] > 126) ? '.' : Text[n]); printf("]\n\n"); /* ------------------------------------*/ /* Read RAM & ROM memory in one block. */ /* ------------------------------------*/ TestOK = HL_READBL(Memory); if (TestOK == STATUS_OK) { printf(" Read whole memory in one block\t\t: ["); for (n = 0; n < 4; n++) { if (n > 0) printf(" \t\t\t\t\t ["); for (Reg = 32 * n; Reg < (32 + 32 * n); Reg++) printf("%c",(Memory[Reg] < 32 || Memory[Reg] > 126) ? '.' : Memory[Reg]); if (n < 3) printf("]ROM\n"); else printf("]RAM\n"); } } else printf(" Read whole memory in one block\t\t: Failed\n"); /* ---------------------------------------- */ /* Write new RAM area (no error handling) : */ /* ---------------------------------------- */ strncpy((char *) NewRAM,"This is the new RAM contents !!!",32); printf(" Write new Hardlock RAM data (save old) : "); for (n = 0; n < 32; n++) printf("%c", (NewRAM[n] < 32 || NewRAM[n] > 128) ? '.' : NewRAM[n] ); printf("\n"); HL_READBL(OldMem); HL_WRITEBL(NewRAM); printf(" Read contents of RAM area \t\t: ["); HL_READBL(Memory); for (n = 0; n <= 32; n++) NewRAM[n] = Memory[96 + n]; for (n = 0; n < 32; n++) printf("%c", (NewRAM[n] < 32 || NewRAM[n] > 128) ? '.' : NewRAM[n] ); printf("]\n\n"); for (n = 0; n <= 32; n++) NewRAM[n] = OldMem[96 + n]; HL_WRITEBL(NewRAM); } else printf("\n\n Hardlock with memory\t\t: No\n\n"); /* ---------------------------------------------- */ /* At last we have to release the API structure. */ /* ---------------------------------------------- */ return (HL_LOGOUT()); }