Datasheet

AN156
11 of 23
2.4 Validating the User’s Certificate
Validating a certificate from a user token looks a lot like the earlier section on initializing the data. The
steps for signing the data are very similar, but the coprocessor-generated signature is merely matched
against the existing signature, rather than being read into the certificate. Also, since the entire certificate
is merely stored on a file in any user token, the process for validating the certificate is identical across all
tokens. When using an unsigned certificate, this step may only consist of checking the user’s account
balance to make sure it makes sense in the system (i.e. it isn’t negative or it isn’t a trillion dollars).
Validating Transaction Data with SHADebit Figure 20
For signed transaction data, the signature of the certificate must be verified with the coprocessor. As a
nice initial check, the validity of the account balance information can be verified first. This can provide a
quick check to avoid verifying the signature of the account information if it’s unnecessary.
Validating the Account Balance Information Figure 21
The verification of the signature looks very similar to how the signature was created in the first place. The
CRC16 is cleared out (set to zero) and the data signature, after being saved in a buffer, is cleared out and
replaced with the system’s initial signature. Since the new signature will not be written back to the part
and the current signature is being verified against the current value of the write cycle counter, the write
cycle counter is not incremented this time for producing the data signature. The entire process is shown in
Figure 22.
Note that, rather than reading the signature back and matching the signature bytes in software, the
coprocessor’s Match Scratchpad command is used. Since this command only transmits 20 bytes of MAC
information to the coprocessor, rather than reading 32 bytes of scratchpad information from the
coprocessor, this technique is slightly faster. When building a fast, responsive debit application, all non-
essential reads/writes will have to be optimized in this manner. In addition, making sure that the correct
MAC isn’t transmitted from the coprocessor gives an invalid user token zero opportunity to grab the right
MAC. These will leave the application less open to holes where the user can take advantage of system
“retries.” For example, if the system was designed to retry the user challenge operation if interrupted, but
eventually repeated a 3-byte random challenge, the user could have stored the appropriate signature.
byte[] acctData = // . . . already known from verifying the user
int wcc = // . . . already known from verifying the user
/* verify the user’s account balance is ‘legal’ */
int balance = (acctData[26]&0x0ff);
balance = (balance << 8) | (acctData [25]&0x0ff);
balance = (balance << 8) | (acctData [24]&0x0ff);
/* MAX_BALANCE, MIN_BALANCE, and DEBIT_AMOUNT are constant integers */
if( balance>MAX_BALANCE )
System.out.println(“Too Much Money!”);
else if( (balance-DEBIT_AMOUNT)<MIN_BALANCE )
System.out.println(“Not enough money to perform transaction!”);
/* Verify user tokens data, including verifying the data signature */
SHADebit debit = new SHADebit(copr, 1000, 50);
debit.verifyTransactionData(user18);