Rockey4 Smart
Rockey4 Smart
Rockey4 Smart
Version 1.4
i
Feitian Technologies Co., Ltd. (“Feitian” for short) will do their best to keep
the content of this document as accurate as possible. But Feitian will not take
the responsibilities for any direct or indirect loss that may be caused by this
document. The content of this document will be amended along with the
updating of the product without notification.
Revision History:
ii
Feitian Technologies Co., Ltd.
All Products of Feitian Technologies Co., Ltd. (Feitian) including, but not limited
to, evaluation copies, diskettes, CD-ROMs, hardware and documentation, and all
future orders, are subject to the terms of this Agreement. If you do not agree with
the terms herein, please return the evaluation package to us, postage and insurance
prepaid, within seven days of their receipt, and we will reimburse you the cost of
the Product, deducting freight and reasonable handling charges.
1. Allowable Use - You may merge and link the Software with other programs
for the sole purpose of protecting those programs in accordance with the usage
described in the manual. You may make archival copies of the Software.
2. Prohibited Use - The Software or hardware or any other part of the Product
may not be copied, reengineered, disassembled, decompiled, revised,
enhanced or otherwise modified, except as specifically allowed in item 1. You
may not reverse engineer the Software or any part of the product or attempt to
discover the Software’s source code. You may not use the magnetic or optical
media included with the Product for the purposes of transferring or storing
data that was not either an original part of the Product, or a Feitian provided
enhancement or upgrade to the Product.
3. Warranty - Feitian warrants that the hardware and Software storage media
are substantially free from significant defects of workmanship or materials for
iii
a time period of twelve (12) months from the date of delivery of the Product to
you.
Warranty claims must be made in writing to Feitian during the warranty period
and within fourteen (14) days after the observation of the defect. All warranty
claims must be accompanied by evidence of the defect that is deemed
satisfactory by Feitian. Any Products that you return to Feitian, or a Feitian
authorized distributor, must be sent with freight and insurance prepaid.
iv
6. Termination - This Agreement shall terminate if you fail to comply with
the terms herein. Items 2, 3, 4 and 5 shall survive any termination of this
Agreement.
v
CE Attestation of Conformity
The equipment complies with the principal protection
requirement of the EMC Directive (Directive 89/336/EEC
relating to electromagnetic compatibility) based on a voluntary
test.
This attestation applies only to the particular sample of the product and its
technical documentation provided for testing and certification. The detailed test
results and all standards used as well as the operation mode are listed in
vi
Quick Start
■ The ROCKEY4 SMART Evaluation Kit is available for developers. It includes a dongle, a package,
a manual, a CD, and an extension cable etc. The evaluation dongle is completely the same as the
formal version of dongle, except that its passwords are public (P1: C44C; P2: C8F8; P3: 0799; P4:
C43B). After receiving the formal version, you can modify its passwords with the initialization tool,
so that others cannot view and/or change the the content of your dongle.
■ Install the ROCKEY4 SMART Developer’s Kit. Run Setup.exe under the root directory of the CD.
The Setup Wizard will guide you through the installation process. (For details, see Chapter 3.)
■ Under directory Tools on the CD, you can find the Dongle Editor (Ry4S_Editor.exe) provided with
the ROCKEY4 SMART dongle, which is a utility for you to make some necessary operations on
the dongle (for details see Chapter 5). The envelope encryption tool, Tools\Envelop\RyEnvX.exe,
enables you to encrypt the PE-structure files without programming work (for more information, see
Chapter 2 in ROCKEY4 SMART License Management).
■ With the function calling (API) protection method, you can embed the ROCKEY4 SMART API in
the protected application program, making the most out of the dongle. In this way, the high-level
security is achieved. Some example codes are provided to you to help understand the API
encryption method. For details on the API encryption, see Chapter 6 and the sample programs
under directory Samples on the CD.
vii
Contents
CHAPTER 1 INTRODUCTION................................................................................. 1
viii
4.6 ALGORITHM AREA ............................................................................................... 15
4.7 USER ID............................................................................................................... 15
4.8 RANDOM NUMBER............................................................................................... 16
4.9 SEED CODE AND RETURN CODES ........................................................................ 16
4.10 TIMER AND COUNTER ........................................................................................ 16
4.11 DONGLE CONFIGURATION UPDATE .................................................................... 16
ix
6.4.7 User ID – Step 8/Step 9................................................................................ 60
6.4.8 Setting Module Characters – Step 10/Step 11/Step 12 ................................. 63
6.4.9 Dongle Cascading – Step 13........................................................................ 67
6.5 ADVANCED APPLICATION EXAMPLES .................................................................. 71
6.5.1 User Memory Area Applications.................................................................. 71
6.5.2 Seed Applications......................................................................................... 81
6.5.3 User ID Applications ................................................................................... 86
6.5.4 Module Applications .................................................................................... 89
6.5.5 Dongles with Same UID for Different Software Products ........................... 95
x
8.2 FAQS ................................................................................................................. 144
xi
Introduction
Chapter 1 Introduction
In this manual, we will describe the components of the encryption software one by one. The
1
ROCKEY4 SMART User’s Guide v1.0
2
Introduction
The ROCKEY4 SMART dongle is a brand-new strong strength encryption product. It employs a
two-level password protection mechanism. With only the first level password, you cannot modify the
special storage area in the dongle. Thus, the software developer and the end user can be granted with
different rights. A time gate is built in the dongle to prevent software tracing. In addition, the software
suppliers are allowed to define hardware encryption algorithms by themselves, thus raise the security
of the encryption key to a new level.
5 High Reliability
The ROCKEY4 SMART dongle has a complet user management system. Different users will
never obtain identical passwords. The hardware ID for each dongle is unique. The password and the
hardware ID are burnt into the CPU, even the manufacturer cannot change them.
6 Comprehensive System Support
The ROCKEY4 SMART dongle supports various kinds of operating systems. The encrypted
application programs support the following platforms: Windows 98 SE/Me/2000/XP/Server
2003/Vista/2008/Windows 7, Linux, and Mac OS.
7 Various Software Interfaces
Software interfaces are available for almost all popular development tools, such as PB, DELPHI,
VB, VC, C++ BUILDER, C#, and Java, etc.
3
ROCKEY4 SMART User’s Guide v1.0
proceed or not, according to the result of the access. The envelope encryption directly encrypts and
handles the compiled files. The advantages are that the developers need neither to learn a lot of
encryption knowledge, nor to modify the source code.If you have no time to learn cryptography or
you have no source code at hand, this is a good choice and convenient. However, the encryption
strength level is not high. That is because the encryption handling is automatically completed by the
programs, so it follows some rules and may be discovered; Moreover, it cannot encrypt the script
language files (e.g., VBA) which cannot be compiled. These are the inherent defects of the envelope
encryption.
The API calling encryption is to choose an appropriate language interface provided with the
dongle to handle access to the dongle according to the language used for development by the
developer. This mode allows you to make full use of the ROCKEY4 SMART dongle. In addition, the
determination of encryption points and method is left to the developer. The security is lifted to a
higher level, especially when the developer uses the internal algorithm functions of the dongle. But
the API calling method should combine with the developer’s source code, and require the developer
to learn and master the API calling method of the ROCKEY4 SMART. Itrequests a higher starting
level of the developer.
4
Hardware Features
2.3 Considerations
Theoretically, the ROCKEY4 SMART dongle is a plug-and-play device, and can be plugged in
and removed at any time. However, instability may be caused if it is removed when being accessed by
a program.
5
ROCKEY4 SMART User’s Guide v1.0
3.1.1 Tools
1) Ry4S_Editor.exe: It is an editing and testing tool located under directory “Tools\Editor”. You
can use it to edit the contents of the dongle, test the dongle, test the contents you have written to the
dongle, write to a set of dongles and more. All functions of the dongle can be utilized with this tool.
2) RyEnvX.exe: It is an envelope encryption tool located under directory “Tools\Envelop”. You
can use it to encrypt your software without programming. It can be used for encrypting more than one
file at a time.
3) .Net program encryption tool: It is located under directory “Tools\NetShell”, used for encrypting
programs developed with C#, VB.NET, Managed C++ etc. It also provides a timing license function.
Flash encryption tool: is provided under directory “Tools\SwfEnv”. By playing an encrypted .swf file
using a flash player with an envelope, the copyright interest of the developer is maintained.
For more information on how to use the envelope encryption tool, the .NET program encryption tool,
and the flash encryption tool, see ROCKEY4 SMART License Management.
6
Development Kit
provided. The calling of the DLL is supported for most of Windows development environments.
7
ROCKEY4 SMART User’s Guide v1.0
8
Development Kit
9
ROCKEY4 SMART User’s Guide v1.0
10
Development Kit
11
ROCKEY4 SMART User’s Guide v1.0
ROCKEY4 SMART installation CD and change the directory to “Driver For Win98” and install it.
12
Basic Concepts
4.1 Passwords
Each developer that orders the ROCKEY4 SMART dongle will be provided with 4
passwords, each has a length of 16 bits. Two of them are basic passwords (or first-level
passwords). The others are advanced passwords (or second-level passwwords). For example, the
public passwords for the evaluation kit are C44C (P1), C8F8 (P2), 0799 (P3), and C43B (P4). The
first two passwords are the first-level passwords. The other two passwords are the second-level
passwords. These passwords are written before the dongle is delivered, and can be modified by
developers. To gain all rights to access the dongle, developers must enter all of the passwords
properly. The advanced passwords should be excluded from the delivery to end users, because the
basic passwords are sufficient for them. At a point in a program where the passwords should
be referenced, both of the advanced passwords must be set to 0. The following sections will
explain which passwords are needed in a specific situation.
4.2 Hardware ID
Each ROCKEY4 SMART dongle contains a globally unique hardware ID. This ID is written
to it by the manufacturer and even the manufacturer cannot change it later. With this ID, the
unique validity can be validated by developers when the encryption is conducted for a particular
user.
Operational attribute:
Readable with both first and second level passwords; not writable with both first and second
13
ROCKEY4 SMART User’s Guide v1.0
level passwords.
14
Basic Concepts
4.7 User ID
It is a serial number unit for managing the published software by developers. The ID is a
32-bit number stored at a particular location inside the dongle. Of course, developers are allowed
to write other information to the location, such as a time value or product management related
information etc.
Operational attribute:
15
ROCKEY4 SMART User’s Guide v1.0
Readable with both first and second level passwords; writable with only second level
passwords.
16
Basic Concepts
updated at a time by calling the API interface, including the user ID, the memory area, the module
value, the algorithm area, and the time and number counter units.
The detailed information about how to use the tools provided by the SDK and use the API
function interface to update the dongle is available in Rockey4 Smart License Management.
17
ROCKEY4 SMART User’s Guide v1.0
5.1 Introduction
The ROCKEY4 SMART Editor is a tool for performing operations, such as modifying,
testing, batch testing, and batch reading and writing, on the ROCKEY4 SMART dongle. This tool
is located at directory “Tools” under the installation directory or on the CD. The interface of the
Editor (Ry4S_Editor.exe) includes 5 parts: the toolbar and dropdown menu, the status bar, the tree
view, the operation status record, and the operation main window (see Figure 5-1).
Figure 5-1
(1) Toolbar and dropdown menu: They are located on the top of the window. Some functions,
18
Dongle Editor
such as print, save and refresh, can be used through activating the icons or the dropdown
menu. A set of shortcut keys and icon buttons are also available there.
(2) The status bar is located at the bottom of the window. It is used for indicating the working
status of the ROCKEY4 SMART dongle, and the operation progress through a progress bar.
The progress bar is not displayed when no operation is performed, or the operation has been
finished. See Figure 5-2.
Figure 5-2
(3) The tree view is located on the top left corner of the window. It displays the version of
current operating system and the ROCKEY4 SMART dongles connected to the computer
with same passwords. You can edit or test a particular dongle by selecting it from the list.
The tree view can be refreshed using the menu item or the button on the toolbar.
(4) The operation status column records the time, result, or error prompts (if any) of all
operations. The list can be cleared using the menu item or the button on the toolbar. See
Figure 5-3.
19
ROCKEY4 SMART User’s Guide v1.0
Figure 5-3
(5) The operation main window involves Input Password, Edit, Test, Self Test etc. Also, you can
use the editing template to operate the ROCKEY4 SMART dongle.The template can be
saved to the disk, or be loaded from the disk. Thus, it is easy for developers to initialize the
ROCKEY4 SMART dongle.
The editor supports drag-and-drop and file relationship. By clicking on the template file of
the explorer, the editor will start and you can edit the file then. The template file can be opened
through the menu or using the explorer. In addition, the content of the template can be printed and
previewed. Without the dongle, the editor is still available. The template file can be used with one
or more dongles. During operating the dongle, you can make operations on the interface. The
progress can be viewed from the progress bar.
Note:
1. Numerical Input/Display
Decimal representation is required for the number of seeds, the number of hours, and the
20
Dongle Editor
Figure 5-4
Be sure to type correct passwords. If the basic passwords are incorrect, the dongle cannot be
used normally. If the basic passwords are correct, but the advanced passwords are not correct, a
problem may occur when writing to the dongle, though the dongle can be found and read.
To perform an operation on the DEMO dongle, click DEMO button. The public passwords
are C44C (P1), C8F8 (P2), 0799 (P3), and C43B (P4).
If you have selected Auto-save password option, the passwords will be encrypted and saved
21
ROCKEY4 SMART User’s Guide v1.0
automatically, so that the action of entering them again and the possibility of entering errors can be
both avoided. After entering the passwords, you are logged into the ROCKEY4 SMART Editor,
and the corresponding dongles with the same passwords will be automatically searched.
5.2.2 Editting
Edit the selected ROCKEY4 SMART dongle. Now you can see the only identity of this
ROCKEY4 SMART dongle, i.e., hardware ID. Even the manufacturer of this dongle cannot
change the hardware ID of the dongle.
As shown in Figure 5-5, the interface includes 6 areas: user memory area, module area,
algorithm area, user ID area, single dongle operation area, and batch operation area.
In the user memory area, you can read data from or write data to the dongle. The data may be in
hex or ASCII format.After you click Read or Write button, a progress bar will be displayed in the
status bar. When the operation is complete, the result will be shown in the status bar.
You can perform an operation on a particular module in the module area. You can input a
value and/or specify if decrease is allowed.
In the algorithm area, you can write a set of algorithm statements to the dongle. An algorithm
statement consists of operands and operators (e.g. A=A+B). (For more information on the
algorithm, see Chapter 7). On the right side of each statement, there is a button, which indicates if
the statement is the starting (S), middle (blank), ending (E), or standlone (SE) statement. If you
click on a button, the incication flag will appear repeatedly. If you have selected “Auto S/E”
option, the indication flags like the starting or the ending flags will be added according to the
algorithm intervals automatically, as shown in Figure 5-5.
22
Dongle Editor
Figure 5-5
You can read a user-defined ID from or write a user-defined ID to the dongle in the “User ID
Zone”.
In the “Batch Operation” area, you can write to a batch of dongles. Type a starting ID in the
“User ID” field. Select a manner in which the IDs will be set (see below). Click “Batch Write”
button. You will write data to a batch of dongles. After that, the data on these dongles is identical,
except that the user ID may be different (depending on the manner in which the ID is generated as
you specified in the following ways).
1) User ID +: The value entered into the User ID field will be written to the first dongle in
the device selection area. After being increased by 1, the value is written to the next
dongle, and so forth. If you initially specify a user ID “10”, the next user ID written to
the second dongle will be “11”.
2) User ID -: The user ID will be decreased by 1.
3) Use Time ID: Use the system time as user ID.
23
ROCKEY4 SMART User’s Guide v1.0
4) No Change: The value in the User ID field will be written to all dongles in the device
selection area without any changes.
In the single dongle operation area, you can perform an operation on a single dongle you
select at a time.
Note: The value of a module and the algorithm cannot be read. You can only
write them.
5.2.3 Testing
Test the selected ROCKEY4 SMART dongle(s). The testing interface includes the user
memory area, the algorithm area, the user ID area, the module property area, and the seed
calculation area, as shown in Figure 5-6.
Figure 5-6
1) The user memory is defined by developers. Data can be displayed in hex or ASCII
format. To read data from the user memory, click “Read” button.
2) In the user algorithm area, choose an algorithm you want to test. If you choose “Calc.
24
Dongle Editor
1” or “Calc. 3”, a module number input box will appear. If you choose Calc. 2, a seed
input box will appear. Type the initial address of the algorithm and the values of
parameters A, B, C, and D in hex format. Enter the module number or seed. Click
“Calculate”. The results will be displayed in “Results” section. The address refers to
the location of the starting statement or the standlone statement.
3) In the user ID area, click “Read” to read a user-defined ID. The size of the user ID area
on the dongle is 32 bits.
4) In the module property area, the validity and degression properties of a module are
displayed. To refresh this area, click “Read” button. If “Dec” buttons are greyed out,
the values of the modules cannot be decreased. Otherwise, you can decrease the value
by 1 by clicking on “Dec” button.
5) The seed calculation area includes 2 sections. Four results of seed calculation are
displayed in the top section. In “Number” field, enter a decimal number. The random
seed and results will be written to a file. By default, the filename is
“Random_Seed.txt” under the executable directory.
25
ROCKEY4 SMART User’s Guide v1.0
Figure 5-7
1) The value of a timer unit can be a number of hours remained or an expiration date.By
checking “Use expiration date”, the timing license mode can be switched to use an
expiration date. After specifying a value, click “Write” to save it to the dongle.
2) Each counter unit stores an integer value. By clicking “Write” button, the integer value
in the text box will be written to the counter unit of the dongle. If you select “Auto
Dec” option, the value of the counter unit will be decreased by 1 each time the
program is executed, until the value equals to 0.
Note:
When using versions earlier than v1.03, it is recommended that both the
number of hours in the timer unit and the number in the counter unit should not
exceed 65534. Moreover, the expiration date in the timer unit should not exceed
2013. Otherwise, the result will not be accurate.
For version 1.03 or higher, the number of hours should be lower than 70000000 and
26
Dongle Editor
the value of the counter should be lower than 400000000 for the same reason.
5.2.5 Self-testing
You can perform a self-testing operation on all ROCKEY4 SMART dongles or on the
selected ones, as shown in Figure 5-8.
Figure 5-8
Important notes:
The content of the dongle will be destroyed by this operation. The data on the dongle
will be cleared after performing the operation, except the password information.
For version 1.03 or higher, the value of the time unit will be the current date after the
self-testing operation. But the value is 0 hour after the operation for other versions.
27
ROCKEY4 SMART User’s Guide v1.0
28
Calling API Functions
29
ROCKEY4 SMART User’s Guide v1.0
WORD* p2,
WORD* p3,
WORD* p4,
BYTE* buffer
);
There is only one function for the ROCKEY4 SMART dongle. All functions of the dongle
can be used by calling this interface. This function has multiple functions in itself.
The following is an example of C language calling. The following descriptions are all based
on this example.
retcode = Rockey(function,handle,lp1,lp2,p1,p2,p3,p4,buffer);
Definition of parameters of ROCKEY function:
Name Type Meaning
Function 16-bit function number API function
Handle Pointer to 16-bit handle Pointer to the operation
handle
lp1 Pointer to 32-bit integer Long parameter 1
lp2 Pointer to 32-bit integer Long parameter 2
p1 Pointer to 16-bit integer Parameter 1
p2 Pointer to 16-bit integer Parameter 2
p3 Pointer to 16-bit integer Parameter 3
p4 Pointer to 16-bit integer Parameter 4
Buffer Pointer to 8-bit integer Pointer to character
buffer
Note:
All interface parameters must be defined in the program. Passing a NULL
pointer is not allowed.
1) function is a 16-bit number, which represents the specific function. The meaning of the
function is defined as follows:
RY_FIND 1 Find dongle
RY_FIND_NEXT 2 Find next dongle
RY_OPEN 3 Open dongle
RY_CLOSE 4 Close dongle
RY_RANDOM 7 Generate random number
RY_SEED 8 Generate seed code
RY_WRITE_USERID 9 Write user ID
RY_READ_USERID 10 Read user ID
30
Calling API Functions
31
ROCKEY4 SMART User’s Guide v1.0
3) lp1 and lp2 are pointers to long integer parameters. Their contents depend on the
specific function.
4) p1, p2, p3, and p4 are pointers to short integer parameters. Their contents depend on the
specific function.
6) buffer is a pointer to the character buffer. Its content depends on the specific function.
Note: p3 and p4 are advanced passwords. They are used for developers to
operate the dongle only, and should not appear in the software provided to end
users. These passwords should be set to “0” when searching for dongles in the
software provided to end users.
1. RY_FIND
For: Check if the dongle with specified passwords exists
Input Parameters:
function = RY_FIND
*p1 = password 1
*p2 = password 2
*p3 = password 3 (optional)
*p4 = password 4 (optional)
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful, the hardware ID of the dongle will be written to *lp1.
2. RY_FIND_NEXT
For: Check if the dongle with specified passwords still exists
32
Calling API Functions
Input Parameters:
function = RY_FIND_NEXT
*p1 = password 1
*p2 = password 2
*p3 = password 3 (optional)
*p4 = password 4 (optional)
*lp1 = the hardware ID of the last dongle found by RY_FIND or RY_FIND_NEXT
Return Values:
If the operation is successful, the hardware ID of the dongle will be written to *lp1.
3. RY_OPEN
For: Open the dongle with specified passwords and hardware ID
Input Parameters:
function = RY_OPEN
*p1 = password 1
*p2 = password 2
*p3 = password 3 (optional)
*p4 = password 4 (optional)
*lp1 = hardware ID
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful, the handle of the dongle is written to *handle.
4. RY_CLOSE
For: Close the dongle with specified handle
Input Parameters:
function = RY_CLOSE
*handle = handle of the dongle
33
ROCKEY4 SMART User’s Guide v1.0
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
5. RY_READ
For: Read the user memory of the dongle
Input Parameters:
function = RY_READ
*handle = handle of the dongle
*p1 = location
*p2 = length
buffer = pointer to the buffer
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful, the content of the memory will be written to the buffer.
6. RY_WRITE
For: Write content to user memory
Input Parameters:
function = RY_WRITE
*handle = handle of the dongle
*p1 = location
*p2 = length
buffer = pointer to the buffer
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
7. RY_RANDOM
For: Get a random number from the dongle
34
Calling API Functions
Input Parameters:
function = RY_RANDOM
*handle = handle of the dongle
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful, the random number is carried by *p1, *p2, *p3, and *p4.
8. RY_SEED
For: Get the return code of the seed
Input Parameters:
function = RY_SEED
*handle = handle of the dongle
*lp2 = seed
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful:
*p1 = return code 1
*p2 = return code 2
*p3 = return code 3
*p4 = return code 4
9. [*] RY_WRITE_USERID
For: Write user-defined ID
Input Parameters:
function = RY_WRITE_USERID
*handle = handle of the dongle
*lp1 = user ID
Return Values:
35
ROCKEY4 SMART User’s Guide v1.0
10. RY_READ_USERID
For: Read user-defined ID
Input Parameters:
function = RY_READ_USERID
*handle = handle of the dongle
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful, the user ID is carried by *lp1.
12. RY_CHECK_MODULE
For: Check module property character
Input Parameters:
function = RY_CHECK_MODULE
*handle = handle of the dongle
*p1 = module number
36
Calling API Functions
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful:
*p2 = 1 indicates that the module is valid
*p3 = 1 indicates that the module can be decreased
14. RY_CALCULATE1
For: Let the dongle perform an operation in the specified way; the result depends on the user
algorithm
Input Parameters:
function = RY_CALCULATE1
*handle = handle of the dongle
*lp1 = start point of operation
*lp2 = module number
*p1 = input value 1
*p2 = input value 2
*p3 = input value 3
*p4 = input value 4
37
ROCKEY4 SMART User’s Guide v1.0
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful:
*p1 = return value 1
*p2 = return value 2
*p3 = return value 3
*p4 = return value 4
15. RY_CALCULATE2
For: Let the dongle perform an operation in the specified way; the result depends on the user
algorithm
Input Parameters:
function = RY_CALCULATE2
*handle = handle of the dongle
*lp1 = start point of operation
*lp2 = seed
*p1 = input value 1
*p2 = input value 2
*p3 = input value 3
*p4 = input value 4
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful:
*p1 = return value 1
*p2 = return value 2
*p3 = return value 3
*p4 = return value 4
38
Calling API Functions
16. RY_CALCULATE3
For: Let the dongle perform an operation in the specified way; the result depends on the user
algorithm
Input Parameters:
function = RY_CALCULATE3
*handle = handle of the dongle
*lp1 = start point of operation
*lp2 = start address of module character
*p1 = input value 1
*p2 = input value 2
*p3 = input value 3
*p4 = input value 4
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful:
*p1 = return value 1
*p2 = return value 2
*p3 = return value 3
*p4 = return value 4
17. RY_DECREASE
For: Perform a decrease operation on the specified module character
Input Parameters:
function = RY_DECREASE
*handle = handle of the dongle
*p1 = module number
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
39
ROCKEY4 SMART User’s Guide v1.0
40
Calling API Functions
41
ROCKEY4 SMART User’s Guide v1.0
42
Calling API Functions
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
26. RY_GET_COUNTER
For: Read the value of a counter unit
Input Parameters:
function = RY_GET_COUNTER
*handle = handle of the dongle
*p1 = number of the counter unit starting from 0
Output:
*P2 = value of counter (WORD type)
*P3 = 1 (degression allowed) or 0 (degression not allowed)
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
27. RY_DEC_COUNTER
For: Decrease the value of a counter unit by 1
Input Parameters:
function = RY_DEC_COUNTER
*handle = handle of the dongle
*p1 = number of the unit
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
43
ROCKEY4 SMART User’s Guide v1.0
29. RY_GET_TIMER
For: Read the value of a timer unit
Input Parameters:
function = RY_GET_TIMER
*handle = handle of the dongle
*p1 = number of the timer unit starting from 0
Output:
*p2 = number of hours
*p4 = 0 (hours) or 1 (date)
buffer = a date and time value of SYSTEMTIME type (expiration date)
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
30. RY_ADJUST_TIMER
For: Synchronize the dongle clock with the computer time if the clock is earlier than the
computer time; do nothing if the clock is later than the computer time.
Input Parameters:
function = RY_ADJUST_TIMER
buffer = computer time of SYSTEMTIME type
Output:
44
Calling API Functions
buffer = If the function is called successfully, a time value of the dongle clock will be
returned (SYSTEMTIME type)
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
31. RY_READ_EX
For: Read user memory of the dongle (for version 1.03 or later)
Input Parameters:
function = RY_READ_EX
*handle = handle of the dongle
*p1 = location
*p2 = length
buffer = Pointer to buffer
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
If the operation is successful, the content of the memory will be read into buffer.
32. RY_WRITE_EX
For: Write to user memory (for version 1.03 or later)
Input Parameters:
function = RY_WRITE_EX
*handle = handle of the dongle
*p1 = location
*p2 = length
buffer = pointer to buffer
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
45
ROCKEY4 SMART User’s Guide v1.0
34. RY_GET_COUNTER_EX
For: Read the value of a counter unit
Input Parameters:
function = RY_GET_COUNTER_EX
*handle = handle of the dongle
*p1 = number of the counter unit starting from 0
Output:
*P3 = 1 (degression allowed) or 0 (degression not allowed)
buffer[0~3] = value of the counter (DWORD type)
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
46
Calling API Functions
36. RY_GET_TIMER_EX
For: Read the value of a timer unit. Before reading, you need to synchronize the dongle clock
with the computer time using RY_ADJUST_TIMER_EX function.
Input Parameters:
function = RY_GET_TIMER_EX
*handle = handle of the dongle
*p1 = number of the timer unit starting from 0
Output:
*p3 = 1 (date) or 2 (hours)
buffer = a date and time value of SYSTEMTIME type (expiration date) or number of hours
(DWORD type)
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
37. RY_ADJUST_TIMER_EX
For: Set the dongle clock to be the same as the computer if the clock is earlier than the
computer time; otherwise, nothing will be done.
Input Parameters:
function = RY_ADJUST_TIMER_EX
buffer = computer time of SYSTEMTIME type
Return Values:
If retcode = 0, the operation is successful; other values indicate errors.
47
ROCKEY4 SMART User’s Guide v1.0
38. RY_GET_TIME_DWORD
For: Convert a date and time value to a number of minutes elapsed from 00:00 (hh:mm) of
Jan. 1, 2006.
Input Parameters:
function = RY_GET_TIME_DWORD
*handle = handle of the dongle
*lp2 = year
*p1 = month
*p2 = day
*p3 = hour
*p4 = minute
Output:
*lp1 = number of minutes elapsed from 2006-1-1 00:00
If retcode = 0, the operation is successful; other values indicate errors.
ERR_SUCCESS 0 No error
ERR_NO_ROCKEY 3 No ROCKEY4 SMART dongle found
ERR_INVALID_PASSWORD 4 ROCKEY4 SMART dongle found, but basic
password is not correct
ERR_INVALID_PASSWORD_OR_ID 5 Error password or hardware ID
ERR_SETID 6 Error in setting hardware ID
48
Calling API Functions
49
ROCKEY4 SMART User’s Guide v1.0
is only for reference. After all, the public experiences have no enough encryption strength to build
applications with high security.
Some key points that you need to pay attention to when programming:
1. P3 and P4 are Advanced passwords enabling developers like you to write to the dongle
when customizing the content of the dongle. They should always be set to zero in
software delivered to end users.
2. Make sure that none of the parameters in the ROCKEY4 Smart functions is a Null
pointer. For example, even if you do not require the Buffer in the above example, you
cannot pass a null to it, otherwise, the result is unpredictable.
The following sample programs are written in VC 6.0. The functions of the dongle will be
demonstrated step by step from an original program that is not encrypted yet. Developers who use
other languages should also read this section carefully. There is no special development skill used
below. The examples can be understood easily.
void main()
{
// Anyone begin from here.
printf("Hello FeiTian!\n");
}
void main()
{
50
Calling API Functions
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4;
DWORD lp1, lp2;
BYTE buffer[1024];
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0; // Program needn't Password3, Set to 0
p4 = 0; // Program needn't Password4, Set to 0
// ==============================================================
printf("Hello FeiTian!\n");
}
This is a simple encryption method. Only a function of the ROCKEY4 SMART API is used.
For details on the function, see function “RY_FIND” in Section 6.2 “ROCKEY4 SMART API
Services”.
Try the above program to observe what happens when the dongle is connected and what
happens when it is not connected.
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
51
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
// ==============================================================
printf("Hello FeiTian!\n");
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
}
6.4.4 User Memory – Step 3/Step 4
The dongle is initialized using the Editor (refer to Chapter 5) or in API mode. Write “Hello
FeiTian!” to the low address area and then read the string. See below in Step 3, Step 4.
Example: Initialize the dongle and write “Hello FeiTian!” – Step 3
#include <windows.h>
#include <stdio.h>
#include “Ry4S.h” // Include ROCKEY4 SMART Header File
52
Calling API Functions
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
retcode = Rockey(RY_FIND, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Not found
{
printf("ROCKEY not found!\n");
return;
}
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0; // Pos
p2 = 14; // Length
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
53
ROCKEY4 SMART User’s Guide v1.0
}
In the above example (Step 3) we have written “Hello FeiTian!” into the dongle. Below in
the following example (Step 4) the string will be read and displayed from the dongle dynamically.
Example: Read content from the memory – Step 4
#include <windows.h>
#include <stdio.h>
#include “Ry4S.h” // Include ROCKEY4 SMART Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0; // Pos
p2 = 14; // Length
buffer[14] = 0;
54
Calling API Functions
retcode = Rockey(RY_READ, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
// ==============================================================
printf("%s\n", buffer);
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
}
6.4.5 Generating a True Random Number with Dongle–
Step 5
Generate a random number at the beginning of the program. Write this random number to a
fixed address of the memory area of the dongle. Verify if the data at the address is equal to the
random number while the program is running. If the program is running on another computer in
this process, a different random number must have been written to the address. Therefore, the
ability to prevent tracing is enhanced.
#include <windows.h>
#include <stdio.h>
#include “Ry4S.h” // Include ROCKEY4 SMART Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
55
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
retcode = Rockey(RY_RANDOM, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Random:%04X,%04X,%04X,%04X\n", p1,p2,p3,p4);
p1 = 0; // Pos
p2 = 4; // Length
buffer[4] = 0;
retcode = Rockey(RY_READ, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
56
Calling API Functions
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Read: %s\n", buffer);
if(buffer)
printf("Hello FeiTian!\n");
else
exit(0);
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
void main()
{
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
57
ROCKEY4 SMART User’s Guide v1.0
return;
}
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
//seed Rockey
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
// Close Rockey
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
printf("\n");
Example: Verify the return code to determine if the program can be continued – Step 7
58
Calling API Functions
#include <windows.h>
#include <stdio.h>
#include “Ry4S.h” // Include ROCKEY4 SMART Header File
void main()
{
WORD retcode;
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
//seed Rockey
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
59
ROCKEY4 SMART User’s Guide v1.0
printf("Hello FeiTian!\n");
else
{
printf("Hello error!\n");
return;
}
// Close Rockey
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
60
Calling API Functions
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
lp1 = 0x88888888;
retcode = Rockey(RY_WRITE_USERID, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Write User ID: %08X\n", lp1);
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
}
Example: Verify the user ID. If it is not 0x88888888, output “Hello DEMO!” – Step 9
#include <windows.h>
#include <stdio.h>
#include “Ry4S.h” // Include ROCKEY4 SMART Header File
void main()
61
ROCKEY4 SMART User’s Guide v1.0
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
lp1 = 0;
retcode = Rockey(RY_READ_USERID, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
if (lp1==0x88888888)
printf("Hello FeiTian!\n");
else
{
printf("Hello DEMO!\n");
return;
}
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
62
Calling API Functions
{
printf("Error Code: %d\n", retcode);
return;
}
}
6.4.8 Setting Module Characters – Step 10/Step 11/Step 12
Configure module character values and properties using the Editor (refer to Chapter 5) or in
API mode. Check if the module is valid and can be decreased in a user program. Determine
whether to activate the associated application module. The module character value may also be
used by the program. Check if the module is allowed to be decreased to limit the number of uses of
software. See below.
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
63
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0;
p2 = 3;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease not allowed\n", p2);
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
}
Example: Output “Hello FeiTian!” in a user program if the module 0 is valid; otherwise, the
program stops running or exits – Step 11
#include <windows.h>
#include <stdio.h>
#include “Ry4S.h” // Include ROCKEY4 SMART Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
64
Calling API Functions
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0;
retcode = Rockey(RY_CHECK_MODULE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
if (p2)
printf("Hello FeiTian!\n");
else
return;
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
65
ROCKEY4 SMART User’s Guide v1.0
}
}
Example: At Step 10, set p2=3 (allowed number of uses) and p3=1 (degression
allowed). That is to say, the number of uses of the software is limited to 3 through
Module 0 (p1=0) The usage limitation is achieved as shown in another example - Step
12:
#include <windows.h>
#include <stdio.h>
#include “Ry4S.h” // Include ROCKEY4 SMART Header File
void main()
{
// ==============================================================
WORD retcode;
WORD handle, p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
retcode = Rockey(RY_OPEN, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
p1 = 0;
retcode = Rockey(RY_CHECK_MODULE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
66
Calling API Functions
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
if (p2!=1)
{
printf("Update Please!\n");
return;
}
if(p3==1)
{
p1=0;
retcode = Rockey(RY_DECREASE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if(retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
// ==============================================================
printf("Hello FeiTian!\n");
retcode = Rockey(RY_CLOSE, &handle, &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
67
ROCKEY4 SMART User’s Guide v1.0
void main()
{
int i, rynum;
WORD retcode;
WORD handle[16], p1, p2, p3, p4; // ROCKEY4 SMART Variable
DWORD lp1, lp2; // ROCKEY4 SMART Variable
BYTE buffer[1024]; // ROCKEY4 SMART Variable
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
68
Calling API Functions
return;
}
}
printf("\n");
rynum = i;
// Do our work
for (i=0;i<rynum;i++)
{
// Read Rockey user memory
p1 = 0; // Pos
p2 = 12; // Length
buffer[12] = 0;
retcode = Rockey(RY_READ, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
lp1=0;
retcode = Rockey(RY_READ_USERID, &handle[i], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
printf("Read User ID: %08X\n", lp1);
p1=0;
retcode = Rockey(RY_CHECK_MODULE, &handle[i], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
69
ROCKEY4 SMART User’s Guide v1.0
printf("Allow Decrease\n");
else
printf("Not Allow Decrease\n");
{
printf("Error Code: %d\n", retcode);
return;
}
}
}
A maximum of 16 dongles can be attached to the same computer at the same time.
The program can be designed to selectively access any dongles.
In the above program, we define a handle array to save the opened dongle handles,
and prepare for the next operation on the specified dongle. We open the dongle at the
same time as we find it, and we close all opened dongle handles before the program exits.
Developers are better off operating in this manner. For a large program, it is OK to
open/close the dongle just once at the beginning/end of the program. Frequent openning
and closing operations will reduce the performance of the program. Don’t worry,
because our opening is in shared mode. Even if another program of yours needs to open
the dongle at the same time, the program will not be blocked.
Note: Functions RY_OPEN and RY_CLOSE are called above. The dongle
70
Calling API Functions
must be opened first for most operations, except for RY_FIND and
RY_FIND_NEXT. This is similar to the operation on the disk files. You should close
the dongle immediately after finishing dongle related operations.
You can find the source code of the above programming examples on the CD or
from the installation directory under “Samples”.
71
ROCKEY4 SMART User’s Guide v1.0
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
BYTE buf[1024];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0;
p4 = 0;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
72
Calling API Functions
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
p1 = 0;
p2 = 10;
p3 = 1;
strcpy((char*)buffer, "Hello ");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: Hello \n");
p1 = 12;
p2 = 12;
p3 = 1;
strcpy((char*)buffer, "FeiTian!");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: FeiTian!\n");
p1 = 0;
p2 = 10;
memset(buffer, 0, 64);
73
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
p1 = 12;
p2 = 12;
memset(buf, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buf);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buf);
printf("\n");
printf("%s\n", strcat(buffer,buf));
{
ShowERR(retcode);
return;
}
}
Example – Step 15: To encrypt and control execution of different modules of the
application with the user memory area of the ROCKEY4 SMART dongle, you can write a serial
number to a location of the user memory area and verify it during the execution of different
modules.
74
Calling API Functions
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
75
ROCKEY4 SMART User’s Guide v1.0
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
p1 = 0;
p2 = 12;
p3 = 1;
strcpy((char*)buffer, "a1b2c3d4e5f6");
p1 = 0;
p2 = 2;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
76
Calling API Functions
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
if (!strcmp(buffer,"a1"))
printf("Run Module 1\n");
else
break;
p1 = 2;
p2 = 2;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
if (!strcmp(buffer,"b2"))
printf("Run Module 2\n");
else
break;
printf("\n");
77
ROCKEY4 SMART User’s Guide v1.0
Example – Step 16: To encrypt and control the number of uses with the user memory area,
you can write a number to the area and decrease it when the application is executed. This step can
be combined with Step 12 for encryption.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
int i, j,num;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0;
p4 = 0;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
78
Calling API Functions
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
p1 = 0;
p2 = 2;
p3 = 1;
strcpy((char*)buffer, "03");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
79
ROCKEY4 SMART User’s Guide v1.0
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: 03\n");
p1 = 0;
p2 = 1;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
num=atoi(buffer);
if(num)
{
printf("Hello FeiTian!\n");
num--;
}
else
{
return;
}
p1 = 0;
p2 = 1;
sprintf(buffer, "%ld", num);
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: %ld\n",num);
80
Calling API Functions
}
printf("\n");
}
}
void main()
{
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0;
p4 = 0;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
81
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
82
Calling API Functions
lp2 = 0x18273645;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
}
Example – Step 18: A string is encrypted with a key and then decrypted. The seed code is
83
ROCKEY4 SMART User’s Guide v1.0
The following illustrates the function of seed code. In your development, the following
should be divided into two parts: the encryption part should be done before the dongle is delivered;
only the decryption part should be presented in user program.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
char str[20] = "Hello FeiTian!";
DWORD mykey = 12345678;
int n, slen;
int i,j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
84
Calling API Functions
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
// Encrypt my data
slen = strlen(str);
lp2 = mykey;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
for (n=0;n<slen;n++)
{
str[n] = str[n] + (char)p1 + (char)p2 + (char)p3 + (char)p4;
}
85
ROCKEY4 SMART User’s Guide v1.0
// Decrypt my data
lp2 = mykey;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
.
}
for (n=0;n<slen;n++)
{
str[n] = str[n] - (char)p1 - (char)p2 - (char)p3 - (char)p4;
}
printf("Decrypted data is %s\n", str);
printf("\n");
}
6.5.3 User ID Applications
Example – Step 19: Developers may write the current date and time as the UID when
initializing the dongle. When the software is running, compare the current system date and time
with the UID. Typically, the current system date and time should be later than the UID.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
86
Calling API Functions
void main()
{
int i, j;
SYSTEMTIME st;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
87
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
lp1 = 0x20021101;
retcode = Rockey(RY_WRITE_USERID, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
lp1 = 0;
retcode = Rockey(RY_READ_USERID, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read User ID: %08X\n", lp1);
sprintf(buffer,"%08X",lp1);
GetLocalTime(&st);
printf("Date:%04d%02d%02d\n",st.wYear,st.wMonth,st.wDay);
sprintf(buf,"%04d%02d%02d",st.wYear,st.wMonth,st.wDay);
if(strcmp(buf,buffer)>=0)
88
Calling API Functions
{
printf("ok!\n");
}
else
break;
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
}
6.5.4 Module Applications
Example – Step 20: Multiple module encryptions allow you to use different dongle modules
to control if the corresponding application modules can execute or be enabled.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
89
ROCKEY4 SMART User’s Guide v1.0
p4 = 0xc43b;
{
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
p1 = 0;
90
Calling API Functions
p2 = 0x2121;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
p1 = 0;
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Check Moudle 0: ");
if (p2)
printf("Run Modul 1!\n");
else
break;
printf("\n");
p1 = 8;
p2 = 0xFFFF;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 8: Pass = %04X Decrease no allow\n", p2);
p1 = 8;
retcode = Rockey(RY_CHECK_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
91
ROCKEY4 SMART User’s Guide v1.0
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Check Moudle 8: ");
if (p2)
printf("Run Modul 2!");
else
break;
printf("\n");
}
}
}
Example – Step 21: This program illustrates how to perform multi-module encryption and
check the status of the modules. Many applications are segmented into program modules that users
may choose or purchase separately. For example, a user may purchase three modules of a
four-module application. Developers can specify that the three modules are valid in the dongle. If
the user wants one more module, developers need only to produce a new dongle in which the
required module is activated and deliver it to the user, thanks for the cascading functionality of the
Rockey4 SMART dongle, without returning the previously delivered dongle, updating it, and
sending it back.
#include <windows.h>
#include <stdio.h>
#include “Ry4S.h” // Include ROCKEY4 SMART Header File
void main()
{
int i, j, rynum;
92
Calling API Functions
WORD retcode;
DWORD HID[16];
if (retcode) // Error
{
printf("Error Code: %d\n", retcode);
return;
}
return;
}
}
printf("\n");
93
ROCKEY4 SMART User’s Guide v1.0
rynum = i;
// Do our work
for (i=0;i<rynum;i++)
{
for (i=0;i<rynum;i++)
{
retcode = Rockey(RY_CLOSE, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
printf("Error Code: %d\n", retcode);
return;
}
}
The above program searches all dongles with the same passwords attached to the computer
and displays the status of each module. “O” means that the module has been activated; and “X”
means that the module has not been activated. You can write some module values with the Editor
and check them as illustrated here. Note that if the content of the module is 0, the module is
inactive; otherwise, the module is active.
94
Calling API Functions
If a module is active, the module can be used. Check the status of the module in your
programs. If a module is active for any one of the dongles, the corresponding program module is
available.
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
WORD handleEnd;
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
{
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
95
ROCKEY4 SMART User’s Guide v1.0
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
printf("\n");
for (j=0;j<i;j++)
{
/*p1 = 0;
p2 = 5;
96
Calling API Functions
p3 = 1;
strcpy((char*)buffer, "Ver10");
retcode = Rockey(RY_WRITE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write:%s\n",buffer);
*/
p1 = 0;
p2 = 5;
memset(buffer, 0, 64);
retcode = Rockey(RY_READ, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n", buffer);
if (!strcmp(buffer,"Ver10"))
{
handleEnd=handle[j];
break;
}
{ //=========A==========
retcode = Rockey(RY_RANDOM, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Random: %04X\n", p1);
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
97
ROCKEY4 SMART User’s Guide v1.0
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
ShowERR(retcode);
return;
}
printf("\n");
}
}
}
Example – Step 23: Recognize the relationship between a set of dongles and a software
product with the user ID of the dongle. For example, if the encrypted user ID is “11111111” (hex),
the corresponding software is Software A.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
WORD handleEnd;
DWORD lp1, lp2;
BYTE buffer[1024];
int i, j;
98
Calling API Functions
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
printf("Find Rock: %08X\n", lp1);
}
99
ROCKEY4 SMART User’s Guide v1.0
printf("\n");
for (j=0;j<i;j++)
{
/*lp1= 0x11111111;
retcode = Rockey(RY_WRITE_USERID, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write User ID: %08X\n", lp1);
*/
lp1 = 0;
retcode = Rockey(RY_READ_USERID, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
if(lp1==0x11111111)
{
handleEnd=handle[j];
break;
}
{ //=======A=============
p1 = 0;
p2 = 12;
p3 = 1;
strcpy((char*)buffer, "Hello Feitian!");
retcode = Rockey(RY_WRITE, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write: %s\n",buffer);
100
Calling API Functions
p1 = 0;
p2 = 12;
buffer[512]=0;
retcode = Rockey(RY_READ, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Read: %s\n",buffer);
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handleEnd, &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
printf("\n");
}
}
101
ROCKEY4 SMART User’s Guide v1.0
102
ROCKEY4 SMART Hardware Algorithms
The algorithm can be defined and written with the Editor. Alternatively, you can use the API
interface RY_WRITE_ARITHMETIC to write the algorithm. Actually, it is easy to develop and add
an algorithm to the ROCKEY4 SMART dongle. We provide detailed introduction below for the
developers to understand and master the techniques.
103
ROCKEY4 SMART User’s Guide v1.0
?: Comparison
value is a decimal figure between 0 and 63.
Note:
? is used to compare two operands. For example: if C = A ? B, the result is as follows:
C A?B B?A
A<B 0 FFFF
A=B FFFF FFFF
A>B FFFF 0
0 or FFFF will be written to C.
An example of algorithm written to the dongle:
A = A + B, B = B + E, C = A * F, D = B + C, H = H ^ H
A, B, C ... are all registers in the dongle. They are 16-bit units. There are 8 such registers inside
the dongle, with identifiers of A, B, C, D, E, F, G, and H respectively.
The register variables whose values may vary depending on the algorithm that is used:
Internal register E
Internal register F
104
ROCKEY4 SMART Hardware Algorithms
Internal register G
Internal register H
Out:
p1 of user program = Internal register A of dongle
p2 of user program = Internal register B of dongle
p3 of user program = Internal register C of dongle
p4 of user program = Internal register D of dongle
Thus, the registers A, B, C, and D are used as user interface variables; and the registers E, F, G,
and H are used as internal variables.
Table 7-2
Internal variables of dongle RY_CALCULATE2
105
ROCKEY4 SMART User’s Guide v1.0
A P1
B P2
C P3
D P4
E Return code 1 of seed (according to the
seed in *lp2)
F Return code 2 of seed (according to the
seed in *lp2)
G Return code 3 of seed (according to the
seed in *lp2)
H Return code 4 of seed (according to the
seed in *lp2)
Table 7-3
Internal variables of dongle RY_CALCULATE3
A P1
B P2
C P3
D P4
E Value in module *lp2
F Value in module (*lp2 + 1)
G Value in module (*lp2 + 2)
H Value in module (*lp2 + 3)
106
ROCKEY4 SMART Hardware Algorithms
Function RY_CALCULATE2
For Perform a dongle operation as specified
Input function = RY_CALCULATE2
Parameters *handle = handle of the dongle
*lp1 = starting point of calculation
*lp2 = seed
*p1 = input value 1
*p2 = input value 2
*p3 = input value 3
*p4 = input value 4
Return If 0 is returned, the operation is successful. Other values indicate errors.
Values If successful:
*p1 = return value 1
*p2 = return value 2
*p3 = return value 3
*p4 = return value 4
Additional When calling an algorithm using this function by the dongle, the initial values of
Descriptions registers E, F, G, and H are the return values of the seed in *lp2. In other words, the
dongle calls function RY_SEED with the value of *lp2, and places the return codes
into registers E, F, G, and H for further user processing.
Function RY_CALCULATE3
For Perform a dongle operation as specified
Input function = RY_CALCULATE3
Parameters *handle = handle of the dongle
*lp1 = starting point of calculation
*lp2 = starting module number
*p1 = input value 1
*p2 = input value 2
*p3 = input value 3
*p4 = input value 4
Return If 0 is returned, the operation is successful. Other values indicate errors.
Values If successful:
107
ROCKEY4 SMART User’s Guide v1.0
For example:
strcpy(buffer,"A=A+E,A=A+F,A=A+G,A=A+H");
p1 = 3;
retcode= Rockey(RY_WRITE_ARITHMETIC,handle,&lp1,&lp2,&p1,&p2,&p3,
108
ROCKEY4 SMART Hardware Algorithms
&p4,buffer);
Obviously, the algorithm to be written is stored into the buffer, with instructions separated
by commas. The dongle will automatically set the first instruction as the beginning of the
algorithm, and the last instruction as the end of the algorithm. In this case:
Address 3 of algorithm area: A=A+E
Address 4 of algorithm area: A=A+F
Address 5 of algorithm area: A=A+G
Address 6 of algorithm area: A=A+H
Address 3 is the starting point of the algorithm in dongle program area. Address 6 is the
ending point of the algorithm in dongle program area. After the instruction at address 6 is
executed, the dongle will return to the user program. If you want to call the program in the
dongle, you must start from the starting point. Otherwise, you will get the result of 4 random
numbers.
109
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_WRITE_ARITHMETIC,handle,&lp1,&lp2,&p1,&p2,&p3,
&p4,buffer);
Then, call the algorithm in the program:
lp1 = 0; // starting point of the algorithm in the dongle
lp2 = 7; // specified module number
p1 = 5; // initial value of A
p2 = 3; // initial value of B
p3 = 1; // initial value of C
p4 = 0xffff; // initial value of D
retcode = Rockey(RY_CALCULATE1,handle,&lp1,&lp2,&p1,&p2,&p3,&p4,buffer);
The dongle carries the following initial values, and starts to execute the instructions from
algorithm area 0:
A = 5 (p1)
B = 3 (p2)
C = 1 (p3)
D = 0xffff (p4)
E = High 16 bits of ID
F = Low 16 bits of ID
110
ROCKEY4 SMART Hardware Algorithms
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
int i, j;
char cmd[] = "H=H^H, A=A*23, F=B*17, A=A+F, A=A+G, A=A<C, A=A^D, B=B^B,
C=C^C, D=D^D";
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
111
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
ShowERR(retcode);
return;
i++;
for (j=0;j<i;j++)
{
/*
p1 = 7;
p2 = 0x2121;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
112
ROCKEY4 SMART Hardware Algorithms
ShowERR(retcode);
return;
}
printf("Set Moudle 7: Pass = %04X Decrease no allow\n", p2);
printf("\n");
*/
p1 = 0;
strcpy((char*)buffer, cmd);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 1\n");
lp1 = 0;
lp2 = 7;
p1 = 5;
p2 = 3;
p3 = 1;
p4 = 0xffff;
retcode = Rockey(RY_CALCULATE1, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=5, p2=3, p3=1, p4=0xffff\n");
printf("\n");
printf("Result = ((5*23 + 3*17 + 0x2121) < 1) ^ 0xffff = 0xBC71\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
113
ROCKEY4 SMART User’s Guide v1.0
printf("\n");
2)Algorithm 2
Example of Algorithm 2 – Step 25: Write algorithm ("A=A+B, A=A+C, A=A+D, A=A+E,
A=A+F, A=A+G, A=A+H"); according to input parameters and internal variables, the result is:
0x7b17
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
114
ROCKEY4 SMART Hardware Algorithms
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
for (j=0;j<i;j++)
{
/*
lp2 = 0x12345678;
115
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
printf("\n");
*/
p1 = 10;
strcpy((char*)buffer, cmd1);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 2\n");
lp1 = 10;
lp2 = 0x12345678;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE2, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("\n");
printf("Result =d03a + 94d6 + 96a9 + 7f54 + 1 + 2 + 3 + 4=0x7b17\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
116
ROCKEY4 SMART Hardware Algorithms
printf("\n");
3)Algorithm 3
Example of Algorithm 3 – Step 26: Write algorithm ("A=A+B, A=A+C, A=A+D, A=A+E,
A=A+F, A=A+G, A=A+H"); according to input parameters and internal variables, the result is: 0x14
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
117
ROCKEY4 SMART User’s Guide v1.0
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
for (j=0;j<i;j++)
{
/*
p1 = 0;
118
ROCKEY4 SMART Hardware Algorithms
p2 = 1;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
p1 = 1;
p2 = 2;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 1: Pass = %04X Decrease no allow\n", p2);
p1 = 2;
p2 = 3;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 2: Pass = %04X Decrease no allow\n", p2);
p1 = 3;
p2 = 4;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
119
ROCKEY4 SMART User’s Guide v1.0
}
printf("Set Moudle 3: Pass = %04X Decrease no allow\n", p2);
printf("\n");
*/
p1 = 17;
strcpy((char*)buffer, cmd2);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 3\n");
lp1 = 17;
lp2 = 0;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE3, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("\n");
printf("Result = 1+2+3+4+1+2+3+4=0x14\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
}
}
120
ROCKEY4 SMART Hardware Algorithms
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD findlp1,truelp1;
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
findlp1=lp1;
121
ROCKEY4 SMART User’s Guide v1.0
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i++;
for (j=0;j<i;j++)
{
/*
p1 = 7;
p2 = 0x2121;
p3 = 0;
122
ROCKEY4 SMART Hardware Algorithms
}
printf("Set Moudle 7: Pass = %04X Decrease no allow\n", p2);
p1 = 0;
strcpy((char*)buffer, cmd);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 1\n");
*/
lp1 = 0;
lp2 = 7;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE1, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
printf("\n");
printf("Moudle 7 : %x\n", p3);
truelp1=MAKELONG(p2,p1);
printf("truelp1 : %x\n",truelp1);
if (findlp1==truelp1)
printf("Hello FeiTian!\n");
else
break;
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
123
ROCKEY4 SMART User’s Guide v1.0
return;
}
printf("\n");
2)Example 2
Example – Step 28: Obtain the return code of a particular seed using the function of Algorithm
2, and compare it with the return code obtained through the same seed when the program runs for the
first time; if they do not match, the program is illegal.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
WORD rc[4];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
124
ROCKEY4 SMART Hardware Algorithms
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
ShowERR(retcode);
return;
}
i++;
125
ROCKEY4 SMART User’s Guide v1.0
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
rc[0] = p1;
rc[1] = p2;
rc[2] = p3;
rc[3] = p4;
// :
p1 = 0;
strcpy((char*)buffer, cmd1);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 2\n");
lp1 = 0;
lp2 = 0x12345678;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE2, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
126
ROCKEY4 SMART Hardware Algorithms
printf("\n");
if(rc[0]==p1 && rc[1]==p2 && rc[2]==p3 && rc[3]==p4)
printf("Hello FeiTian!\n");
else
break;
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
}
}
3) Example 3
Example – Step 29: You can get the values stored in the 16 modules using the function
of Algorithm 3. Remember that the modules may not be read, even with the advanced
passwords. You may write some important data to the modules or perform some other
operations.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
127
ROCKEY4 SMART User’s Guide v1.0
BYTE buffer[1024];
int i, j;
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
128
ROCKEY4 SMART Hardware Algorithms
ShowERR(retcode);
return;
}
i++;
for (j=0;j<i;j++)
{
/*
p1 = 0;
p2 = 1;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
p1 = 1;
p2 = 2;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 1: Pass = %04X Decrease no allow\n", p2);
p1 = 2;
p2 = 3;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
129
ROCKEY4 SMART User’s Guide v1.0
{
ShowERR(retcode);
return;
}
printf("Set Moudle 2: Pass = %04X Decrease no allow\n", p2);
p1 = 3;
p2 = 4;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
p1 = 0;
strcpy((char*)buffer, cmd2);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 3\n");
lp1 = 0;
lp2 = 0;
p1 = 0;
p2 = 0;
p3 = 0;
p4 = 0;
retcode = Rockey(RY_CALCULATE3, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
130
ROCKEY4 SMART Hardware Algorithms
printf("\n");
printf("Moudle 0: %x\n",p1);
printf("Moudle 1: %x\n",p2);
printf("Moudle 2: %x\n",p3);
printf("Moudle 3: %x\n",p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
}
}
4)Example 4
Example – Step 30: You can use all of the 3 algorithms in a program. In the program below, 4
algorithm segments are written to the dongle, and the 3 algorithms are all used.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include “Ry4S.h”
void main()
{
WORD handle[16], p1, p2, p3, p4, retcode;
DWORD lp1, lp2;
BYTE buffer[1024];
131
ROCKEY4 SMART User’s Guide v1.0
int i, j;
int t1,t2,t3;
char cmd[] = "H=H^H, A=A*23, F=B*17, A=A+F, A=A+G, A=A<C, A=A^D, B=B^B,
C=C^C, D=D^D";
char cmd1[] = "A=A+B, A=A+C, A=A+D, A=A+E, A=A+F, A=A+G, A=A+H";
char cmd2[] = "A=A+B, A=A+C, A=A+D, A=A+E, A=A+F, A=A+G, A=A+H";
char cmd3[] = "H=H^H,A=A|A, B=B|B, C=C|C,D=A+B,D=D+C";
p1 = 0xc44c;
p2 = 0xc8f8;
p3 = 0x0799;
p4 = 0xc43b;
retcode = Rockey(RY_FIND, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Find Rock: %08X\n", lp1);
retcode = Rockey(RY_OPEN, &handle[0], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
i = 1;
while (retcode == 0)
{
retcode = Rockey(RY_FIND_NEXT, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode == ERR_NOMORE) break;
if (retcode)
{
ShowERR(retcode);
return;
}
retcode = Rockey(RY_OPEN, &handle[i], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
132
ROCKEY4 SMART Hardware Algorithms
{
ShowERR(retcode);
return;
}
i++;
printf("\n");
for (j=0;j<i;j++)
{
p1 = 7;
p2 = 0x2121;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 7: Pass = %04X Decrease no allow\n", p2);
printf("\n");
lp2 = 0x12345678;
retcode = Rockey(RY_SEED, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Seed: %04X %04X %04X %04X\n", p1, p2, p3, p4);
printf("\n");
p1 = 0;
p2 = 1;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
133
ROCKEY4 SMART User’s Guide v1.0
ShowERR(retcode);
return;
}
printf("Set Moudle 0: Pass = %04X Decrease no allow\n", p2);
p1 = 1;
p2 = 2;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 1: Pass = %04X Decrease no allow\n", p2);
p1 = 2;
p2 = 3;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 2: Pass = %04X Decrease no allow\n", p2);
p1 = 3;
p2 = 4;
p3 = 0;
retcode = Rockey(RY_SET_MODULE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Set Moudle 3: Pass = %04X Decrease no allow\n", p2);
printf("\n");
p1 = 0;
strcpy((char*)buffer, cmd);
134
ROCKEY4 SMART Hardware Algorithms
ShowERR(retcode);
return;
}
printf("Write Arithmetic 1\n");
lp1 = 0;
lp2 = 7;
p1 = 5;
p2 = 3;
p3 = 1;
p4 = 0xffff;
retcode = Rockey(RY_CALCULATE1, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=5, p2=3, p3=1, p4=0xffff\n");
p1 = 10;
strcpy((char*)buffer, cmd1);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 2\n");
lp1 = 10;
lp2 = 0x12345678;
p1 = 1;
135
ROCKEY4 SMART User’s Guide v1.0
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE2, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
p1 = 17;
strcpy((char*)buffer, cmd2);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic 3\n");
lp1 = 17;
lp2 = 0;
p1 = 1;
p2 = 2;
p3 = 3;
p4 = 4;
retcode = Rockey(RY_CALCULATE3, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Input: p1=1, p2=2, p3=3, p4=4\n");
printf("Result = 1+2+3+4+1+2+3+4=0x14\n");
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
136
ROCKEY4 SMART Hardware Algorithms
t3=p1;
printf("\n");
p1 = 24;
strcpy((char*)buffer, cmd3);
retcode = Rockey(RY_WRITE_ARITHMETIC, &handle[j], &lp1, &lp2, &p1, &p2, &p3,
&p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Write Arithmetic \n");
lp1 = 24;
lp2 = 7;
p1 = t1;
p2 = t2;
p3 = t3;
p4 = 0;
retcode = Rockey(RY_CALCULATE1, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4,
buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("Calculate Output: p1=%x, p2=%x, p3=%x, p4=%x\n", p1, p2, p3, p4);
retcode = Rockey(RY_CLOSE, &handle[j], &lp1, &lp2, &p1, &p2, &p3, &p4, buffer);
if (retcode)
{
ShowERR(retcode);
return;
}
printf("\n");
137
ROCKEY4 SMART User’s Guide v1.0
dongle. The following example illustrates this by 3 stages: Firstly, the source code before encryption
is shown; secondly, the dongle is initialized; at last, it is the program used by the end users after
encryption.
Source program:
#include "stdafx.h"
#include "DrawCircle.h"
#include "DrawCircleDoc.h"
#include "DrawCircleView.h"
#include "DrawParamDlg.h"
#include "DrawMethodDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
TRACE("Origin\n");
CirclePlotPoints(pDC,iCenterX,iCenterY,x,y);
m_lpCircleBuf[0].x = x;
m_lpCircleBuf[0].y = y;
m_nPointCount=1;
while(x<y)
{
x++;
if(p<0)
{
p+=2*x+1;
}
else
{
y--;
p+=2*(x-y)+1;
}
138
ROCKEY4 SMART Hardware Algorithms
TRACE("%d,(%d,%d);",p,x,y);
CirclePlotPoints(pDC,iCenterX,iCenterY,x,y);
m_lpCircleBuf[m_nPointCount].x = x;
m_lpCircleBuf[m_nPointCount].y = y;
m_nPointCount++;
}
TRACE("\n");
retcode = Rockey(RY_FIND,&handle[0],&lp1,&lp2,&p1,&p2,&p3,&p4,buffer);
if(retcode)
{
ReportErr(retcode);
return 0;
}
printf("Find successfully\n");
retcode = Rockey(RY_OPEN,&handle[0],&lp1,&lp2,&p1,&p2,&p3,&p4,buffer);
if(retcode)
{
ReportErr(retcode);
return 0;
}
139
ROCKEY4 SMART User’s Guide v1.0
printf("Open successfully\n");
p1 = 10;
retcode =
Rockey(RY_WRITE_ARITHMETIC,&handle[0],&lp1,&lp2,&p1,&p2,&p3,&p4,cmdstr);
if(retcode)
{
ReportErr(retcode);
return 0;
}
printf("Write arithmetirc successfully\n");
retcode = Rockey(RY_CLOSE,&handle[0],&lp1,&lp2,&p1,&p2,&p3,&p4,buffer);
return 0;
}
#include "DrawCircleDoc.h"
#include "DrawCircleView.h"
#include "DrawParamDlg.h"
#include "DrawMethodDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
WORD p1=0xc44c,p2=0xc8f8,p3=0x0799,p4=0xc43b;
DWORD lp1,lp2;
WORD handle[16];
BYTE buffer[1024];
short p1,p2,p3,p4;
140
ROCKEY4 SMART Hardware Algorithms
CirclePlotPoints(pDC,iCenterX,iCenterY,x,y);
TRACE("Hardware\n");
m_lpCircleBuf[0].x = x;
m_lpCircleBuf[0].y = y;
m_nPointCount=1;
while(x<y)
{
p1 = p;
p2 = x;
p3 = y;
p4 = seed;
if(!RunRockey((WORD&)p1,(WORD&)p2,(WORD&)p3,(WORD&)p4))
{
// AfxMessageBox("Runtime error");
break;
}
if(p<0)
{
p = p1;
}
else
{
p = p2;
y--;
}
x++;
TRACE("%d,(%d,%d);",p,x,y);
CirclePlotPoints(pDC,iCenterX,iCenterY,x,y);
m_lpCircleBuf[m_nPointCount].x = x;
m_lpCircleBuf[m_nPointCount].y = y;
m_nPointCount++;
}
TRACE("\n");
}
lp1 = 10;
retcode = Rockey(RY_CALCULATE1,&handle[0],&lp1,&lp2,&A,&B,&C,&D,buffer);
141
ROCKEY4 SMART User’s Guide v1.0
if(retcode)
return FALSE;
else
return TRUE;
7.4 Considerations
The algorithm area in the ROCKEY4 SMART has 128 words. That is to say, the
ROCKEY4 SMART dongle supports as many as 128 instructions or 128 algorithms,
because every instruction takes one word. Developers do not need to consider the starting
and ending flags of an algorithm, because they are handled by the dongle. In practice, this
means that if you write a 2-instruction algorithm to the dongle, and then a 3-instruction
algorithm, the two algorithms will not be recognized as a single 5-instruction algorithm. If
the starting point used in calculations is incorrect, the result will be unpredictable.
142
ROCKEY4 SMART Hardware Algorithms
the developers can randomly obtain some data of the system as the seed code, like
system date, etc.
3. Avoid using the duplicate encryption methods in your application as far as
possible - If you repeatedly use the same protection method in your application, it will
be easier for the cracker to find the rule and crack your application. In other words, if
a developer uses different encryption methods in one program, every time the cracker
will spend more energy to trace the program, and constantly face new cracking tasks.
If the developer uses some dynamic encryption methods, the cracking will be even
more difficult.
4. Encrypt some character string and data – Encrypt some character strings and data
in the program need to be encrypted, to let the decryption rely on the existence of the
ROCKEY4 SMART dongle. If these character strings and data cannot be properly
decrypted, program failure or illegality will be caused. (Please refer to the example in
Step 18 for specific applications)
5. Use API encryption and Envelope encryption together – The best protection will
be achieved by using a complex and dynamic implementation of the ROCKEY4
SMART API, and then protecting the new executable files with the envelope.
143
ROCKEY4 SMART User’s Guide v1.0
Chapter 8 FAQs
This chapter covers some frequently asked questions and some solutions when using the
ROCKEY4 SMART dongles.
8.2 FAQs
1. What is the evaluation kit?
Answer: The evaluation kit includes a dongle provided to developers for evaluation purpose. It also
includes a product package, a manual, and a CD etc. The dongle is the same as the formal version,
except that its passwords are public and unified.
2. Is the password mechanism of the ROCKEY4 SMART dongle secure?
Answer: It is very secure. The users can use our tool to generate 4 passwords in two levels, each has a
length of 16 bits. The first level is the basic passwords, which are used to perform basic operations on
the dongle. The second level is the advanced passwords, which are specially used by the developers
for controlling writing to the dongle and defining encryption algorithms. The advanced passwords
must not appear in the software delivered to end users, so that they cannot be obtained even by tracing.
Moreover, if the advanced passwords are incorrect and the operation of writing to the high address
144
FAQs
area of the user memory is attempted for 4 times in succession, the dongle will be locked for 2
seconds. During the locking period, no operation will be accepted. This measure prevents hackers
from using a program for password attempts.
3. What is the dongle with the same passwords?
Answer: After a batch of dongles is delivered to the developers, the users may modify the passwords
of the dongles to be identical, using our password initialization tool. After the encryption task is done,
the developers produce their own software in a large amount by compressing it into CDs. Then the
developers sell the encrypted software out together with the dongles, eliminating the needs to
recompile every set of software one by one.
4. Is it true that a data sharer can share a dongle?
Answer: The sharer can be prevented by using our methods. Actually, it is very simple. You can
design your program to generate a random number and write it to a fixed address on the dongle when
the program starts, and verify the content at that address with the random number during the runtime.
If during this time the program is also running on another computer, a different random number must
have been written to the fixed address.
5. Will the performance of the software be compacted significantly if I write a complex
algorithm to the ROCKEY4 SMART dongle?
Answer: No. During the testing, we got that the running time difference between the simplest
algorithm and the most complex algorithm is merely tens of milliseconds. The difference will not be
perceived at all if the algorithm is not called frequently.
6. Why is my USB dongle recognized as an unknown device?
Answer: This problem occurs rarely. Interference may exist in your environment or your dongle is not
in good connection with your computer. Please remove and attach your dongle again.
7. My computer is equipped with a USB port and installed Windows 98. Why can’t I see the
USB device in Device Manager?
Answer: Maybe the USB support option is disabled in BIOS settings.
8. How can I update the software of the dongle?
Answer: If you are our evaluation user, you will receive updates from us regularly. Otherwise, go to
145
ROCKEY4 SMART User’s Guide v1.0
146
Appendix A Directory Structure Of CD
On the ROCKEY4 SMART CD, you can find a complete ROCKEY4 SMART developer’s kit, which
is briefly introduced here in the following table.
Directory Description
Static libraries, dynamic libraries, COM components, OCX
API
controls required for development
Documentation that describes the calling interface of the
Docs
dongle functions and the usage of tools
Driver For Win98 HID driver for Windows 98
Include Header files required for development
Management License manager software, production tool software
Samples Examples of various programming languages
Support Jet driver with an Access database for Windows 98
Some software tools, including the Editor, the flash
Tools encryption tool, the envelope encryption tool and the .Net
program encryption tool
147