{
Symbol file for the 'Dallas Primary' group (U.S./Canada version).
CiBPublicExp | = 01 { User Objects} |
CiBModulus | = 02 |
CiBPrivateExp | = 03 |
Input1 | = 04 |
SignCount | = 05 |
TimeStamp | = 06 |
SignCiBKey | = 07 |
GpInfo | = 08 |
GpCertificate | = 09 |
OutExp | = 0A |
OutMod | = 0B |
EncryptCiBKey | = 0C |
DecryptCiBKey | = 0D |
EncryptOutKey | = 0E |
Output | = A0 { Auto objects used by Dallas Primary } |
Output2 | = A1 |
RegNumber | = A3 |
Padding | = A4 |
Functions: | { Declare software ICs referenced in scripts } |
SHA1 | = 01 |
--------------------------------------------------------------------------------------------------------------------------------
{
The Dallas Semiconductor Primary Group contains 4 primary scripts and their supporting data objects. Three of the scripts (documented below) provide RSA encryption/decryption capability. The fourth script is used for signature generation.
Begin
Locked:
EncryptCiBKey,
DecryptCiBKey,
EncryptOutKey,
SignCiBKey: Script;
Private:
Script EncryptCiBKey;
{
Script DecryptCiBKey;
{
Script EncryptOutKey;
{
Script SignCiBKey;
{
{
Ver 1.00 : Initial symbol file creation
3/11/97
CiBPublicExp | = 01 { User Objects } |
CiBModulus | = 02 |
CiBPrivateExp | = 03 |
Input1 | = 04 |
SignCount | = 05 |
TimeStamp | = 06 |
SignCiBKey | = 07 |
GpInfo | = 08 |
GpCertificate | = 09 |
Output1 | = A0 { Auto objects used by Dallas Primary } |
Output2 | = A1 |
RegNumber | = A3 |
Padding | = A4 |
Functions: | { Declare software ICs referenced in scripts } |
SHA1 | = 01 |
--------------------------------------------------------------------------------------------------------------------------------
{
The Dallas Semiconductor Primary Group contains one primary script and its supporting data objects. This script is used for signature generation.
Transaction Group('Dallas Primary');
Begin
Locked:
SignCiBKey: Script;
Private:
Script SignCiBKey;
{
The Crypto iButton API function calls that are required to communicate with the Crypto iButton to perform the digital signature operation are outlined below:
1. Import Constant Values from the Symbol File
Const
CiBPublicExp | = 1; { User Objects } |
CiBModulus | = 2; |
CiBPrivateExp | = 3; |
Input1 | = 4; |
SignCount | = 5; |
TimeStamp | = 6; |
SignCiBKey | = 7; |
GpInfo | = 8; |
GpCertificate | = 9; |
OutExp | = 10; { U.S./Canada Version Objects } |
OutMod | = 11; |
EncryptCiBKey | = 12; |
DecryptCiBKey | = 13; |
EncryptOutKey | = 14; |
Output1 | = 160; { Auto objects used by Dallas Primary } |
Output2 | = 161; |
RegNumber | = 163; |
Padding | = 164; |
2. Provide Function Prototypes for the Required API Calls
Function SelectCiB(P: Pointer): Boolean;
StdCall; External 'CIBAPI.DLL';
Function GetGroupID(lpGroupName, lpGroupID, lpRP: Pointer): Boolean;
StdCall; External 'CIBAPI.DLL';
Function ReadCiBObject(GroupID: Byte; lpGroupPIN:
Pointer; ObjectID: Byte;
lpObject, lpRP: Pointer): Boolean; StdCall;
External 'CIBAPI.DLL';
Function WriteCiBObject(GroupID: Byte; lpGroupPIN:
Pointer; ObjectID: Byte;
lpObject, lpRP: Pointer): Boolean; StdCall;
External 'CIBAPI.DLL';
Function InvokeScript(GroupID: Byte; lpGroupPIN:
Pointer; ObjectID: Byte;
RunTime: Word; lpRP: Pointer): Boolean; StdCall;
External 'CIBAPI.DLL';
Function GetCiBError: Word; StdCall; External 'CIBAPI.DLL';
3. Declare Constants, Types, and Variables
MaxPINLen | = 8; |
MaxNameLen | = 16; |
MaxPacketLen | = 128; |
MaxObjLen | = 128; |
Name : String | = 'Dallas Primary'; { Dallas Semiconductor Primary Group } |
LargeKeyTime | = 1500; { Estimated time parameter for large key encryption } |
SmallKeyTime | = 250; { Estimated time parameter for small key encryption } |
Type
TGroupName = Record
TCiBObj = Record
TRetPacket = Record
Var
lpGroupPin | : PGroupPin; |
lpGroupName | : PGroupName; |
lpObject | : PCiBObj; |
lpRP | : PRetPacket; |
GroupPin | : TGroupPin; |
GroupName | : TGroupName; |
CiBObject | : TCiBObj; |
CiBRP | : TRetPacket; |
GroupID | : Byte; |
4. Initialize Data Structures
Begin
lpGroupPin | := @GroupPin; |
lpGroupName | := @GroupName; |
lpObject | := @CiBObject; |
lpRP | := @CiBRP; |
5. Establish a Communication Link to the Crypto iButton
Function AttachCiB: Boolean;
{
Var
Begin
6. Transmit the Data to be Signed to the Crypto iButton
F := WriteCiBObject(GroupID, lpGroupPin, Input1, lpObject, lpRP);
(Note that if there is a Group PIN, the structure pointed to by lpGroupPin must contain the PIN. If there is no group PIN, the Len parameter of the GroupPin structure must be zero.)
If F returns True, the operation was successful, otherwise call the GetCiBError API function to determine the type of error that has occurred. Values returned by GetCiBError and their meanings are given in the Cryptographic iButton Firmware Reference Manual. Two particular errors that should be considered are ERR_BAD_GROUP_PIN = $82 and ERR_INACTIVE = $D1. The first error occurs when the part expects a PIN but the value of the PIN specified in the GroupPIN variable is missing or incorrect. The second error occurs if the activation of the Crypto iButton has expired and the device requires reactivation from the Dallas Semiconductor activation website.
7. Execute the Signature Script
F := InvokeScript(GroupID, lpGroupPin, SignCiBKey, LargeKeyTime, lpRP);
Note that the value of the estimated time parameter LargeKeyTime given in Step 3 above is based on an RSA key length of 1024 bits. If the key length is less than this value, a smaller value of LargeKeyTime may be used. (The SmallKeyTime value is used when encrypting or verifying a digital signature with a small public exponent, such as 65537.)
If the function returns True, the operation was successful, otherwise call the GetCiBError API function to determine the type of error that has occurred. On successful completion, the script leaves the results of the digital signature calculation in the output objects Output1 and Output2.
8. Read Back the Two Components of the Completed Digital Signature
F := ReadCiBObject(GroupID, lpGroupPin, Output1, lpObject, lpRP);
Again, the function returns True if it was successful. The data is returned through the pointer lpObject. To create the digital signature, the Crypto iButton appended a packet of random fill to this data to make it one bit shorter than the modulus. Then it was signed by exponentiating it with the private key. The following function call returns the result of this operation:
F := ReadCiBObject(GroupID, lpGroupPin, Output2, lpObject, lpRP);
If it returns True, the data is returned through the pointer lpObject. The response to a challenge requires that both the data from Output1 and the data from Output2 be returned to the remote party who provided the challenge. For a digital signature, both the contents of Object1 and the contents of Object2 must be appended to the original document to form the digital signature.
Note that because of the random fill, every digital signature and response to a challenge is different, even if the message digest or challenge is the same. This feature helps to defeat certain kinds of attacks on the security of the Crypto iButton.
The Crypto iButton API function
calls that are required to communicate with the Crypto iButton
to perform the encryption and decryption operations are outlined
below:
1. Perform Steps 1 through 5 described in Appendix
C above to set up the environment and prepare the Crypto iButton
for use.
2. EncryptOutKey
a. Load the Exponent F := WriteCiBObject(GroupID, lpGroupPIN, OutExp,
lpObject, lpRP);
If the function returns True, the exponent
has been written successfully into OutExp. b. Load the Modulus
F := WriteCiBObject(GroupID, lpGroupPIN, OutMod,
lpObject, lpRP);
If the function returns True, the modulus has
been written successfully into OutMod. c. Load the Session Key
F := WriteCiBObject(GroupID, lpGroupPIN, Input1,
lpObject, lpRP);
If the function returns True, the session key
has been written successfully into Input1. d. Invoke the Script
If the function returns True, the encryption
has been performed successfully and the result is waiting for
retrieval in Output1. Note that the use of the SmallKeyTime parameter
is justified if the public exponent supplied in step 2.a. above
is small. A full-length exponent requires use of LargeKeyTime. e. Retrieve the Result
If the function returns True, the session key
encrypted with the intended recipient's public key is available
in the variable pointed to by lpObject. 3. DecryptCiBKey
a. Load the Encrypted Session Key F := WriteCiBObject(GroupID, lpGroupPIN, Input1,
lpObject, lpRP);
If the function returns True, the encrypted
session key has been written successfully into Input1. b. Invoke the Script
If the function returns True, the decryption
has been performed successfully and the result is waiting for
retrieval in Output1. c. Retrieve the Result
If the function returns True, the decrypted
session key is available in the variable pointed to by lpObject. 4. EncryptCiBKey
a. Load the Session Key F := WriteCiBObject(GroupID, lpGroupPIN, Input1,
lpObject, lpRP);
If the function returns True, the session key
has been written successfully into Input1. b. Invoke the Script
If the function returns True, the encryption
has been performed successfully and the result is waiting for
retrieval in Output1. c. Retrieve the Result
If the function returns True, the encrypted
session key is available in the variable pointed to by lpObject.To use this script, the intended recipient's
public key must first be loaded into OutExp and OutMod, and the
random session key must be loaded into Input1. Then the EncryptOutKey
script must be executed, and the result retrieved from Output1:
First put the RSA exponent of the intended
recipient's key into the variable pointed to by lpObject, then
execute the API function:
First put the RSA modulus of the intended recipient's
key into the variable pointed to by lpObject, then execute the
API function:
First put the session key used for encrypting
the message into the variable pointed to by lpObject, then execute
the API function:
F := InvokeScript(GroupID, lpGroupPin, EncryptOutKey,
SmallKeyTime, lpRP);
F := ReadCiBObject(GroupID, lpGroupPin, Output1,
lpObject, lpRP);
To use this script, the encrypted session key
is written into Input1, the script is invoked, and the decrypted
result is read from Output1:
First put the session key used for encrypting
the message into the variable pointed to by lpObject, then execute
the API function:
F := InvokeScript(GroupID, lpGroupPin, DecryptCiBKey,
LargeKeyTime, lpRP);
F := ReadCiBObject(GroupID, lpGroupPin, Output1,
lpObject, lpRP);
To use this script, the session key is written
into Input1, the script is invoked, and the encrypted result is
read from Output1:
First put the session key used for encrypting
the message into the variable pointed to by lpObject, then execute
the API function:
F := InvokeScript(GroupID, lpGroupPin, DecryptCiBKey,
LargeKeyTime, lpRP);
F := ReadCiBObject(GroupID, lpGroupPin, Output1,
lpObject, lpRP);
{
Ver 1.00 : Initial symbol file creation
11/10/96
Ver 1.00 -> 2.00 : Added DalPubCrypt script symbol info.
DalPubExp | = 01 { User objects } |
DalModulus | = 02 |
Input1 | = 03 |
ActivateCiB | = 04 |
RandomChlg | = 05 |
GlobDest | = 06 |
ActiveSeconds | = 07 |
DalPubCrypt | = 08 |
Output1 | = A0 { Auto objects used by Dallas, CA2 } |
Temp | = A2 |
--------------------------------------------------------------------------------------------------------------------------------
{
Ver 1.00 | : Initial group file creation |
11/10/96 | |
Ver 1.00 -> 2.00 | : Added DalPubCrypt script to assist with |
3/11/97 | decryption of certificates signed with the Dallas Semiconductor private key. |
TransactionGroup('Dallas, CA2');
Begin
Input1: | InputData; |
Locked:
DalPubExp: | Exponent; |
DalModulus: | Modulus; |
RandomChlg: | SALT; |
GlobDest: | Destructor; |
ActiveSeconds: | ClockOffset; |
Output1: | OutputData; |
ActivateCiB, | |
DalPubCrypt: | Script; |
Private:
Temp: | WorkingRegister; |
Script ActivateCiB;
{
Script DalPubCrypt;
{