Esempio n. 1
0
//-------------------------------------------------------------------------
// 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;
}
Esempio n. 2
0
//-------------------------------------------------------------------------
// 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);
}