AN156
16 of 23
Initializing the Coprocessor Figure 29
3.2 Initializing the User Token
Initializing the user token consists of two steps. First, install the master authentication secret and bind it to
the iButton to produce the unique secret for the token. Second, write the certificate file to the iButton. It is
actually a little more complicated than it may initially sound. The DS1963S has eight secrets that
correspond to the 16 pages of memory (where each secret is shared by two pages). The certificate file
must be written to a page which has a write cycle counter, which limits it to the last eight pages of the
device’s memory banks. Also, the certificate file must be written to one of the pages whose corresponding
secret is the secret where the master authentication secret was installed. But, the 1-Wire file API doesn’t
allow the specification of a page number for the file to be stored on. The best that can be done is to give
the file one of the reserved extensions that ensures special treatment. Extensions 101 and 102, for
example, are reserved for files that must be written on pages with write cycle counters if the device has
them (see AN114). One solution for this is to use the 1-Wire file API to create an empty stub file to write
the certificate. This creates the proper directory entries for the certificate so it can be located dynamically.
/* Find the first SHA device on the 1-Wire Net */
FindNewSHA(copr.portnum, copr.devAN, FALSE);
/* Install the master authentication secret and the master signing secret */
InstallSystemSecret18(copr.portnum, copr.signPageNumber, copr.signPageNumber&7,
inputSignSecret, 47, FALSE))
InstallSystemSecret18(copr.portnum, copr.authPageNumber, copr.authPageNumber&7,
inputAuthSecret, 47, TRUE))
/* prepare the service file to write to the coprocessor */
int namelen = strlen(copr.providerName);
int auxlen = strlen(copr.auxilliaryData);
uchar* coprFile = malloc(80 + namelen + auxlen);
memcpy(coprFile, copr.serviceFilename, 5);
coprFile[5] = copr.signPageNumber;
coprFile[6] = copr.authPageNumber;
coprFile[7] = copr.wspcPageNumber;
coprFile[8] = copr.versionNumber;
memcpy(&coprFile[13], copr.bindData, 32);
memcpy(&coprFile[45], copr.bindCode, 7);
memcpy(&coprFile[52], copr.signChlg, 3);
coprFile[55] = namelen;
coprFile[56] = 20; // length of the initial signature
coprFile[57] = auxlen;
memcpy(&coprFile[58], copr.providerName, namelen );
memcpy(&coprFile[58+namelen], copr.initSignature, 20 );
memcpy(&coprFile[78+namelen], copr.auxilliaryData, auxlen );
coprFile[78+namelen+auxlen] = copr.encCode;
coprFile[79+namelen+auxlen] = copr.ds1961Scompatible;
/* Create FileEntry for “COPR.000” file */
FileEntry feCopr;
memcpy(feCopr.Name, “COPR”, 4);
feCopr.Ext = 0;
/* using the 1-Wire file commands in public domain kit, format the device */
int handle, maxwrite;
owFormat(copr.portnum, copr.devAN);
owCreateFile(copr.portnum, copr.devAN, &maxwrite, &handle, &feCopr);
owWriteFile(copr.portnum, copr.devAN, handle, coprFile, 80+namelen+auxlen);