Software Authorization Library version 2.00 utilizing the 1-Wire Public Domain Kit 0. Introduction 1. 1-Wire Devices Supported 2. Using the SoftAuth API 3. Sample Output of Example Binaries 4. File Descriptions 5. Function Descriptions 0. Introduction ---------------- The Software Authorization Library is a set of simple functions that utilize the 1-Wire Public Domain Kit to provide an easy-to-use API for user-validation services. The software programmer could utilize our serial port (DS9097U), parallel port (DS1410E), or USB (DS9490) 1-Wire adapters as a security dongle to protect their software from unauthorized use. The examples included are built for Win32 (Windows XP, 2000, ME, 98/95), but can be built using the necessary link files for any platform supported by the 1-Wire Public Domain Kit: http://www.ibutton.com/software/1wire/wirekit.html The design of the API is centered on the simplest use-cases possible, to make integration into the software programmer's existing code painless. There are 3 main services provided by the API: - Initializing a device - Authenticating a device - Clearing a device (so it is no longer a valid part of the system) 1. 1-Wire Devices Supported ---------------------------- Currently, the Software Authorization Library supports 3 different types of 1-Wire devices: - DS1977 A password-protected EEPROM device capable of storing 32kilobytes. Passwords provide both write- and read-protection. - DS1963S A 512-byte NVRAM device with integrated SHA, 8 write-only 8-byte secrets, and 8 read-only 4-byte write-cycle counters for secure data verification. Data write-protection is achieved with the use of a digital signature that shows if data is manipulated. - DS1961S/DS2432 (iButton/chip) A 128-byte EEPROM device with integrated SHA and a write-only 8-byte secret which provides both data verification and write- protection. Use of each device is automatically excluded from the API unless a flag is defined, at compile time, to allow the use of each device that will be supported. The following flags should be defined when appropriate: - SA_USE_DS1977 - SA_USE_DS1963S - SA_USE_DS1961S (use this flag for both DS1961S and DS2432) 2. Using the SoftAuth API -------------------------- Each of the 3 main steps begin with a call to saBeginSession and end with a call to saEndSession, like so: void main(void) { DeviceStruct device; int rslt = saBeginSession("{1,6}", &device); // . . . . . . . . . . . . . . . . // init, auth, or clear the device // . . . . . . . . . . . . . . . . saEndSession(&device); // . . . . . . . . . . . . . . . . // user code could begin here // . . . . . . . . . . . . . . . . } The first argument to saBeginSession is the port descriptor for which port type and number to open and discover the 1-Wire adapter. USB is port type 6, serial is port type 5, and parallel is port type 2. So, to open COM1, the programmer would use "{1,5}". To open LPT3, use "{3,2}". And to open USB1, use "{1,6}". The return value from saBeginSession will be <0 if there was a hardware error with the port it tried to open, =0 if no valid 1-Wire devices were found on the given 1-Wire adapter, and >0 if the port was opened and a device was found. After a successful call, the DeviceStruct parameter will contain the handle that references the opened 1-Wire port and the 64-bit serial number of the 1-Wire device found on that port. To initialize the device for first-time use, call the saInitDevice function. Note that subsequent calls to saInitDevice may fail if the device is not cleared in between each call. Specifically, if the device is a DS1977, it is assumed that the passwords have not been enabled on the device each time it is initialized. The arguments to saInitDevice are the DeviceStruct, a keyphrase of the software programmer's choice, and a data packet to store securely on the device. A call to saInitDevice may look like the following: unsigned char[] keyphrase = "this is my keyphrase"; unsigned char[] data = "this is my data"; unsigned int dataLen = 15; if(saInitDevice(&device, keyphrase, data, dataLen)) puts("Init Successful"); After this function is complete, the device will contain either an 8-byte password or 8-byte secret and a Triple-DES encrypted copy of the data packet provided. The password, secret, and data packet will be different for each and every device, since the key for Triple-DES encryption is derived from both the keyphrase provided and the 64-bit unique serial number of each device. Authentication of the device is done by calling the saAuthDevice function. The keyphrase used must be the same as used when initializing the device, otherwise the data packet returned will be garbage. The saAuthDevice function, and by association the whole SoftAuth Library, is designed towards actually storing application critical data in the hardware data packet. It is not recommended to just use it for authentication only: // dont do this!! if(saAuthDevice(&device, keyphrase, dataLen)) userCode(); // NOT RECOMMENDED else return 0; Doing something as shown above makes it very easy for a cracker to simply watch the value of the return of functions and see which points are jumped. He can then simply work back to find the point where the code calls the authentication routine, remove the call, and jump straight to the user code. If, on the other hand, meaningful data was stored in the data packet, the cracker who is attempting to crack the software will, at the very least, have to be a registered user of the software or have his hands on a valid dongle which belongs to a registered user of the software. Granted, given enough time the cracker may even be able to find a way to make the program work without this meaningful data packet, but the goal here is to make the cracker's job much, much harder. The meaningful content of the data packet is entirely up to the software programmer. The tricker the better, the more integral to the functionality the better. For starters, a software programmer could create a registry key that stores system settings and preferences for the user during the install. When the program is run, the meaningful data packet could provide the full path to this registry key. If a cracker finds a way to skip the authentication step and still run the 'userCode()', he will still be without a way of finding the registry key the program needs. So, the call to saAuthDevice might end up looking more like this: uchar[] registryData; saAuthDevice(&device, keyphrase, dataLen); registryData = getRegistryData(device.contents); userCode(registryData); To retire a 1-Wire device from the SoftAuth library, such that it is no longer recognized as a valid device with a valid encrypted data packet, use the saClearDevice function. To erase all of the memory (which could take a while on the DS1977) use 0 for the length of data to erase. Otherwise, specify the exact size of the data packet to erase just the part that shouldn't be left lying around. Note that subsequent calls to saClearDevice without a call to saInitDevice may fail. Specifically, the DS1977's passwords will not be in the expected state after the first call to saClearDevice. To see an example of each of the 3 main pieces of the Software Authorization Library, look at the 3 binaries in the examples folder: SoftAuthInit, SoftAuthCheck, and SoftAuthClear. The SoftAuthInit and SoftAuthClear apps are complete, and can be used in a production environment. The code from SoftAuthCheck can be used as an example for the software programmer to use when integrating the Software Authorization Library into a program. 3. Sample Output of Example Binaries ------------------------------------- SoftAuthInit Usage ------------------- SoftAuthInit "{x,y}" "key phrase" "data packet" "{x,y}" - port number (x) and port type (y) {1,6} = USB1, {1,5} = COM1, {1,2} = LPT1 "key phrase" - phrase used in generating key for encryption, decryption, and authentication. "data packet" - actual data to be written to device. SoftAuthInit Output -------------------- $ SoftAuthInit.exe "{1,6}" "private keyphrase" "important data" SoftAuth Init routine Port: {1,6} key phrase: "private keyphrase" data packet: "important data" Successfully acquired port Found Device: romID: 18 43 DC 09 00 00 00 CA data packet: 69 6D 70 6F 72 74 61 6E 74 20 64 61 74 61 Length of data packet = 14 Init Successful SoftAuthCheck Usage -------------------- SoftAuthCheck "{x,y}" "key phrase" z "{x,y}" - port number (x) and port type (y) {1,6} = USB1, {1,5} = COM1, {1,2} = LPT1 "key phrase" - phrase used in generating key for encryption, decryption, and authentication. z - length of the expected data packet stored on the device SoftAuthCheck Output --------------------- $ SoftAuthCheck "{1,6}" "private keyphrase" 14 SoftAuth Check routine Port: {1,6} key phrase: "private keyphrase" length of data packet: 14 Successfully acquired port Found Device: romID: 18 43 DC 09 00 00 00 CA Auth Complete data packet: 69 6D 70 6F 72 74 61 6E 74 20 64 61 74 61 data packet = "important data" SoftAuthClear Usage -------------------- SoftAuthClear "{x,y}" "key phrase" z "{x,y}" - port number (x) and port type (y) {1,6} = USB1, {1,5} = COM1, {1,2} = LPT1 "key phrase" - phrase used in generating key for encryption, decryption, and authentication. z - (optional) length of data to erase from device SoftAuthClear Output -------------------- $ SoftAuthClear "{1,6}" "private keyphrase" 14 SoftAuth Clear routine Port: {1,6} key phrase: "private keyphrase" length of data to erase: 14 Successfully acquired port Found Device: romID: 18 43 DC 09 00 00 00 CA Clear Complete 4. File Descriptions --------------------- /src SoftAuth.c The main library file. Contains the high-level functions for the Software Authorization Library. d3des.c Library file for Triple-DES routines. Taken from public domain. /src/owpd mb*.c, ow*.c, rawmem.c, pw77.c, sha*.c 1-Wire Public Domain Kit files for memory, PIN, and SHA functions of the various 1-Wire devices. /include SoftAuth.h, d3des.h, ownet.h, mb*.h, sha*.h Header files for SoftAuth library and owpd kit files. /lib owlib.lib 1-Wire Public Domain Kit library which includes all low-level functions for accessing the various adapter types supported by the kit. /example SoftAuthExample.dsw VC6 Workspace for the 3 example apps. /example/SoftAuthInit SoftAuthInit.c Sample application for initializing a device for use in the Software Authorization Library. /example/SoftAuthCheck SoftAuthCheck.c Sample application for authenticating a device initialized for use in the Software Authorization Library. /example/SoftAuthClear SoftAuthClear.c Sample application for clearing a device, so that it may no longer be used as a valid device in the Software Authorization Library. 5. Function Descriptions ------------------------- /// /// Initializes the SA library, opens the 1-Wire port, and finds /// a 1-Wire device supported by the SA library. Only returns /// supported devices, such as the DS1963S, DS1961S/DS2432, and DS1977. /// Supported devices can be set at compile time by adjusting which of /// the 'use' flags are defined, such as SA_USE_DS1961S, SA_USE_DS1963S, /// and SA_USE_DS1977. /// /// @param szPortStr the hardware port to open for 1-Wire adapter. /// @param pDevStruct DeviceStruct for holding device and port info /// @return <0 for hardware port failure /// =0 for no devices found, /// >0 for success in opening port and finding device /// int saBeginSession(char* portStr, DeviceStruct* pDevStruct); /// /// De-initializes the SA library and closes the 1-Wire port. /// /// @param pDevStruct DeviceStruct for holding device and port info /// void saEndSession(DeviceStruct* pDevStruct); /// /// Initializes the device, setting any pins or secret information, and /// stores the data packet on the device in an encrypted form. /// /// @param pDevStruct DeviceStruct for holding device and port info /// @param szKeyPhrase secure phrase which is used to derive PIN, Secret, /// and encryption keys. /// @param data data packet to store on device /// @param dataLen length of data packet /// @return 0 if unsuccessful, >0 otherwise /// int saInitDevice(DeviceStruct* pDevStruct, char* szKeyPhrase, uchar* data, unsigned int dataLen); /// /// Authenticates the device, using the derived PIN or SHA secret, and /// decrypts the data packet stored on the device. /// /// @param pDevStruct DeviceStruct for holding device and port info /// @param szKeyPhrase secure phrase which is used to derive PIN, Secret, /// and encryption keys. /// @param dataLen Expected length of data packet on device /// @return 0 if unsuccessful, >0 otherwise /// int saAuthDevice(DeviceStruct* pDevStruct, char* szKeyPhrase, unsigned int dataLen); /// /// Clears the PIN or secret information from the device, as well as /// erasing any stored data packets. /// /// @param pDevStruct DeviceStruct for holding device and port info /// @param szKeyPhrase secure phrase which is used to derive PIN, Secret, /// and encryption keys. /// @param dataLen Length of data to erase, 0 for all memory. /// @return 0 if unsuccessful, >0 otherwise /// int saClearDevice(DeviceStruct* pDevStruct, char* szKeyPhrase, unsigned int dataLen);