//------------------------------------------------------------------------- // Answers a random challenge by performing an authenticated read of the // user's account information. // // 'user' - Structure for holding user token information. // 'chlg' - 3-byte buffer of challenge data. // // Return: the value of the write cycle counter for the account page. // or -1 if there is an error // int AnswerChallenge(SHAUser* user, uchar* chlg) { int addr = user->accountPageNumber << 5; user->writeCycleCounter = -1; memcpy(&user->accountFile[20], chlg, 3); //set the serial number owSerialNum(user->portnum, user->devAN, FALSE); if(user->devAN[0]==0x18) { // for the DS1963S OWASSERT( EraseScratchpadSHA18(user->portnum, addr, FALSE), OWERROR_ERASE_SCRATCHPAD_FAILED, -1 ); OWASSERT( WriteScratchpadSHA18(user->portnum, addr, user->accountFile, 32, TRUE), OWERROR_WRITE_SCRATCHPAD_FAILED, -1 ); user->writeCycleCounter = ReadAuthPageSHA18(user->portnum, user->accountPageNumber, user->accountFile, user->responseMAC, TRUE); } else if(user->devAN[0]==0x33||user->devAN[0]==0xB3) { // for the DS1961S OWASSERT( WriteScratchpadSHA33(user->portnum, addr, &user->accountFile[16], FALSE), OWERROR_WRITE_SCRATCHPAD_FAILED, -1 ); user->writeCycleCounter = ReadAuthPageSHA33(user->portnum, user->accountPageNumber, user->accountFile, user->responseMAC, TRUE); } return user->writeCycleCounter; }
//------------------------------------------------------------------------- // Installs new service data on a user token. // // 'copr' - Structure for holding coprocessor information. // 'user' - Structure for holding user token information. // 'secret' - the authentication secret to install on user token. // // Return: If TRUE, new service installation succeeded. // If FALSE, an error occurred. // SMALLINT InstallServiceData(SHACopr* copr, SHAUser* user, uchar* secret, int secret_length, int initialBalance) { short handle; int maxwrite; FileEntry fe; uchar fullBindCode[15]; //make sure user has a file directory structure memcpy(fe.Name, copr->serviceFilename, 4); fe.Ext = copr->serviceFilename[4]; // install master authentication secret if(user->devAN[0]==0x18) { //need to format the device if(!owFormat(user->portnum, user->devAN)) return FALSE; //and create an empty stub for his account information if(!owCreateFile(user->portnum, user->devAN, &maxwrite, &handle, &fe)) return FALSE; //need to know what page the stub is on user->accountPageNumber = fe.Spage; // set the serial number to that of the user owSerialNum(user->portnum, user->devAN, FALSE); OWASSERT( InstallSystemSecret18(user->portnum, user->accountPageNumber, user->accountPageNumber&7, secret, secret_length, FALSE), OWERROR_INSTALL_SECRET_FAILED, FALSE ); } else if((user->devAN[0]&0x7F)==0x33) { // set the serial number to that of the user owSerialNum(user->portnum, user->devAN, FALSE); //because of copy-authorization, we need to install the //secret first on the DS1961S and _then_ format the system OWASSERT( InstallSystemSecret33(user->portnum, 0, 0, secret, secret_length, FALSE), OWERROR_INSTALL_SECRET_FAILED, FALSE ); //need to format the device if(!owFormat(user->portnum, user->devAN)) return FALSE; //and create an empty stub for his account information if(!owCreateFile(user->portnum, user->devAN, &maxwrite, &handle, &fe)) return FALSE; //need to know what page the stub is on user->accountPageNumber = fe.Spage; } else { return FALSE; } // format the bind code properly // first four bytes of bind code memcpy(fullBindCode, copr->bindCode, 4); // followed by the pagenumber fullBindCode[4] = (uchar)user->accountPageNumber; // and 7 bytes of the address of current device memcpy(&fullBindCode[5], user->devAN, 7); // followed by the last 3 bytes of bind code memcpy(&fullBindCode[12], &(copr->bindCode[4]), 3); // create a unique secret for iButton if(user->devAN[0]==0x18) { DebitFile* accountFile = (DebitFile*)user->accountFile; OWASSERT( BindSecretToiButton18(user->portnum, user->accountPageNumber, user->accountPageNumber&7, copr->bindData, fullBindCode, TRUE), OWERROR_BIND_SECRET_FAILED, FALSE ); // do a read just to get value of writecycle counter user->writeCycleCounter = ReadAuthPageSHA18(user->portnum, user->accountPageNumber, user->accountFile, NULL, TRUE); //setup user account file with initial balance IntToBytes(accountFile->balanceBytes,3,initialBalance); // set transaction ID accountFile->transID[0] = 0; accountFile->transID[0] = 0; } else if((user->devAN[0]&0x7F)==0x33) { DebitFile33* accountFile33 = (DebitFile33*)user->accountFile; OWASSERT( BindSecretToiButton33(user->portnum, user->accountPageNumber, 0, copr->bindData, fullBindCode, TRUE), OWERROR_BIND_SECRET_FAILED, FALSE ); // Call VerifyUser just to get the user's secret in wspc if(!VerifyUser(copr, user, TRUE)) return FALSE; //Record A //setup user account file with initial balance IntToBytes(accountFile33->balanceBytes_A,3,initialBalance); // set transaction ID accountFile33->transID_A[0] = 0; accountFile33->transID_A[0] = 0; //Record B //setup user account file with initial balance IntToBytes(accountFile33->balanceBytes_B,3,initialBalance); // set transaction ID accountFile33->transID_B[0] = 0; accountFile33->transID_B[0] = 0; } //sign the data with coprocessor and write it out return UpdateServiceData(copr, user); }