AN156
7 of 23
certificate to the data page. The current value of the write cycle counter is then incremented by 1, since
the data that it will be verified with is about to be written.
The certificate’s signature is produced on the coprocessor using the Sign Data command. The command
has a few variable inputs. The first of which is the data page that is to be signed. In this case, that page is
the actual account file (as constructed in Figure 9), which is written to the signing page of the
scratchpad. The rest of the inputs are all stored on the scratchpad of the coprocessor (referred to as the
coprocessor’s “signing scratchpad”). The first parameter stored on the scratchpad is the value of the write
cycle counter for the part. Next is the page number of the user token’s memory pages that hold the
account file. This is followed by least significant 56 bits of the user token’s address (64-bit Rom ID
minus the CRC8). The last parameter is the 3-byte constant challenge set when the coprocessor was
initialized.
Retrieving Write-Cycle Counter from DS1963S Figure 10
Setting up the Coprocessor’s Scratchpad for Data Signing Figure 11
SHAiButtonCopr Helper Method for Signing Data Figure 12
The helper method shown in Figure 12 can be broken down into the necessary container methods used to
implement signing data. Figure 13 illustrates the process for creating a data signature.
byte[] signScratchpad = new byte[32];
/* assign the wcc to the coprocessor’s “signing” scratchpad */
signScratchpad[8] = (wcc&0x0ff);
signScratchpad[9] = ((wcc>>=8)&0x0ff);
signScratchpad[10] = ((wcc>>=8)&0x0ff);
signScratchpad[11] = ((wcc>>=8)&0x0ff);
/* get the page number of the account file */
signScratchpad[12] = (byte)acctPage;
/* get the Rom ID of the user token */
System.arraycopy(owc18.getAddress(),0,signScratchpad, 13, 7);
/* get the signing challenge */
System.arraycopy(signingChlg, 0, signScratchpad, 20, 3);
/* sign the data with the coprocessor and return the mac right in the data */
copr.createDataSignature(acctData, signScratchpad, acctData, 2);
/* if using a DS1963S, need to get the value of the write-cycle counter. Doing a
* read authenticated page on the device will accomplish this. */
owc18.readAuthenticatedPage(acctPage, rawData, 0);
/* get the value of the write cycle counter for DS1963S user token only */
int wcc = (rawData[35]&0x0ff);
wcc = (wcc << 8) | (rawData[34]&0x0ff);
wcc = (wcc << 8) | (rawData[33]&0x0ff);
wcc = (wcc << 8) | (rawData[32]&0x0ff);
wcc += 1; // and increment it since we are going to write to the device
AN156
8 of 23
Signing Data with Coprocessor at Container-Level Figure 13
For the data in the account file byte array to be a valid account file, it must have an inverted, two-byte
CRC16 at the end of the file. More detail on what makes a valid file on the 1-Wire file structure can be
found in AN114.
Adding Inverted CRC16 to 1-Wire File Figure 14
Writing the account file to the data page of the DS1963S user token is fairly easy. There is a utility
function provided in the container class for writing a page of data, the exact function which is used to
write the account data to the coprocessor for signing in the above code block.
2.3 Authenticating the User Token
Authenticating the user token involves a simple challenge-response scheme. First, the coprocessor is used
to generate a 3-byte, pseudo-random challenge. This challenge is then written to the scratchpad of the
user token and the Read Authenticated Page command is issued (see DS1963S data sheet). This returns
the entire contents of the memory page followed by the value of the write cycle counter for the page and
the write cycle counter for the secret location. The scratchpad of the DS1963S user token will contain the
20-byte SHA result of the user’s unique authentication secret, the page number the data was read from,
the serial number of the user token, and the random challenge. The coprocessor is then used to reproduce
this SHA result, ensuring that the user token is a valid member of the system.
Authenticating User Token with SHADebit Figure 15
The process for verifying a user is the same for both signed and unsigned transactions. Naturally, this can
be broken down into simple steps using the SHAiButtonCopr class and the SHAiButton
User class. The
code snippet presented in Figure 16 demonstrates the basic implementation of the user verification
method in the transaction classes (minus the error checking).
/* calculate the inverted CRC16 */
int crc = ~CRC16.compute(acctData, 0, acctData[0]+1, acctPage);
/* now the file is ready to be written */
acctData[30] = (byte)crc;
acctData[31] = (byte)(crc>>8);
/* write the account data to the signing page of the coprocessor */
coprDevice.writeDataPage(signPageNumber, acctData);
/* write the signScratchpad to the scratchpad of the coprocessor */
coprDevice.writeScratchpad(signPageNumber, 0, acctData, 0, 32);
/* sign the data and read the signature*/
coprDevice.SHAFunction(coprDevice.SIGN_DATA_PAGE, signPageNumber << 5);
coprDevice.readScratchpad(signScratchpad, 0);
/* place the resulting signature in the certificate */
System.arraycopy(signScratchpad, 8, acctData, 2, 20);
/* Verify user tokens authentication response, same for signed and unsigned */
SHADebit debit = new SHADebit(copr, 65536, 2);
debit.verifyUser(user18);
AN156
9 of 23
Using SHAiButtonCopr and SHAiButtonUser for Authentication Figure 16
Figure 17 illustrates how to use the OneWireContainer18 class to produce a random challenge. Also
included in that caption is the declaration of the variables used in the rest of the code snippets for this
section.
Using the Coprocessor to Generate a Random Challenge Figure 17
After performing the steps in Figure 17, the scratchpad buffer of the coprocessor now contains the 20-
byte result of a SHA calculation, starting at index 8. Since any three bytes are as good as any other three
for a challenge, it is safe to leave the result as it is in the scratchpad. Indices 20 to 22 of the coprocessor’s
scratchpad hold the challenge bytes that will be used for the Read Authenticated Page. Using these three
particular bytes makes it unnecessary to write the challenge back to the coprocessor later.
byte[] rawData = new byte[42];
byte[] scratchpad = new byte[32];
byte[] responseMAC = new byte[20];
byte[] challenge = new byte[3];
/* Use the coprocessor to generate the challenge, page number is irrelevant but a
* highly used page will generate a more random (less repeating) number */
coprDevice.eraseScratchPad(authPageNumber);
coprDevice.SHAFunction(ibcL.COMPUTE_CHALLENGE, authPageNumber << 5);
coprDevice.readScratchPad(scratchpad, 0);
/* copy the challenge bytes into challenge buffer */
System.arraycopy(scratchpad, 20, challenge, 0, 3);
/* Use coprocessor to generate a random challenge */
copr.generateChallenge(0, challenge, 0);
/* issue challenge to user getting back the account data, response MAC, and the
* value of the write-cycle counter */
int wcc = user18.readAccountData(challenge, 0, rawData, 0, responseMAC, 0);
scratchpad[8] = (wcc&0x0ff);
scratchpad[9] = ((wcc>>=8)&0x0ff);
scratchpad[10] = ((wcc>>=8)&0x0ff);
scratchpad[11] = ((wcc>>=8)&0x0ff);
/* get user’s full binding code */
fullBindCode = user18.getFullBindCode();
/* create the coprocessor’s “signing” scratchpad */
System.arraycopy(fullBindCode, 4, scratchpad, 12, 8);
System.arraycopy(challenge, 0, scratchpad, 20, 3);
if(copr.verifyAuthentication(fullBindCode, rawData, scratchpad, responseMAC,
user18.getAuthorizationCommand()))
System.out.println(“User Token Authentication Successful!”);

DS1963S-F5+

Mfr. #:
Manufacturer:
Maxim Integrated
Description:
iButtons & Accessories SHA iButton
Lifecycle:
New from this manufacturer.
Delivery:
DHL FedEx Ups TNT EMS
Payment:
T/T Paypal Visa MoneyGram Western Union

Products related to this Datasheet