This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SHA1 demo code

Other Parts Discussed in Thread: BQ40Z50-R1

Dears,

is there any SHA1 demo code can share to me?

We are using bq40z50-R1 authentication.

thanks.

  • Mingmo,

    You can find example code for the MSP430 here. There is a lib directory in the zip package that includes C code for the SHA-1.

    Todd

  • Todd,

    thank you.

    //*****************************************************************************
    //  MSP430F23x0 Demo - bq26100 Authentication using SHA-1 HMAC Algorithm
    //
    //  The MSP430 performs the SHA-1 HMAC that is compatible with the bq26100.
    //  Once the processor is done computing the HMAC, the main() function calls
    //  the SDQ commands necessary to have the bq26100 perform authentication and
    //  compare its results with the ones of the MCU.
    //  The functions used to implement the SHA1 as computed by the microcontroller
    //  were developed following the same guidance as described in the "How to
    //  Implement SHA-1/HMAC Authentication for bq26100" document.  It can be
    //  found at www.ti.com by searching for SLUA389.
    //
    //                MSP430F23x0
    //             -----------------
    //         /|\|              XIN|-
    //          | |                 |
    //          --|RST          XOUT|-
    //            |                 |
    //            |             P1.0|--> STATUS
    //            |             P1.1|<-> SDQ
    //
    //  R. Wu
    //  Texas Instruments Inc.
    //  February 2010
    //  Built with IAR Embedded Workbench Version: 4.21A
    //*****************************************************************************
    
    #include <stdlib.h>
    #include "..\..\lib\VLO_RAND\vlo_rand.h"
    #include "..\..\lib\SDQ\MSP430_SDQLIB.h"
    #include "..\..\lib\SDQ\SDQ_writeByte.h"
    #include "..\..\lib\SHA1_HMAC\SHA1_HMAC.h"
    
    #define P1_STATUS BIT0
    #define STATUS_FAIL (P1OUT&=~P1_STATUS)
    #define STATUS_GOOD (P1OUT|=P1_STATUS)
    #define STATUS_TOGGLE (P1OUT^=P1_STATUS)
    #define SDQ_ERROR 0x00
    
    extern UINT8 Message[RANDMESGNUMBYTES]; // Random message sent to the bq26100
    extern UINT8 Key[SECRETKEYNUMBYTES];    // Secret key - should match bq26100 
    extern UINT32 Digest_32[5];             // Result of SHA1/HMAC obtained by MCU
    extern UINT32 H[5];
    
    UINT8 DeviceID[DEVICEIDNUMBYTES];           // Stores the Device ID data
    UINT8 Digest[DIGESTNUMBYTES];               // SHA1 response from the bq26100
    
    //*****************************************************************************
    // void error(void)					      				
    //																
    // Description : Continuously blinks the status LED to denote error condition			 
    // Returns : Nothing
    //*****************************************************************************
    void error(void)
    {
      unsigned int j;
    
      while (1)
      {
        STATUS_TOGGLE;
        for (j = 0; j < DEVICEIDNUMBYTES; j++)
        {
          SDQ_delayUSEC(8000);
        }
      }
    }
    
    //*****************************************************************************
    // void main(void)
    //
    // Description : This is the main function. It calls the SDQ	
    //		 communication and the SHA1 function. Results 
    //		 is displayed through the status LED.					 
    // Arguments : read - generic variable for read functions
    //	       i - used for repeat loops	
    // Global Variables : Message[], Key[], Digest[], Digest_32[]
    // Returns : Nothing
    //*****************************************************************************
    void main(void)
    {
      UINT8 read;
      int i;
     
      WDTCTL = (WDTPW | WDTHOLD);               // Stop watchdog timer 
      P1SEL &= ~P1_STATUS;                      // P1.x GPIO function
      P1DIR |= P1_STATUS;                       // P1.x STATUS output direction
      STATUS_FAIL;                              // Initialize STATUS = FAIL
    
      // Generate random seed to create the random message
      read = (UINT8)TI_getRandomIntegerFromVLO();
      srand(read);
      for (i = 0; i < RANDMESGNUMBYTES; i++)
      {
        Message[i] = rand();
      }
      SHA1_authenticate();                      // Perform my own SHA1 (Host side)
      
      SDQ_init();                               // Initialize SDQ comm module
      
      // TODO: Insert the private 128-bit key that is stored in the bq26100
      // Key[15..8] = K1 (highest 64 bits of the key)
      // Key[ 7..0] = K0 (lowest 64 bits of the key)
      // In this example 0x00000000000000000000000000000000 is used since a fresh
      // unprogrammed bq26100 device should contain all 0's for its 128-bit key.
      for (i = 0; i < SECRETKEYNUMBYTES; i++)
      {
        Key[i] = (UINT8)0x00;    
      }
    
      // Read Control Register
      SDQ_reset();
      read = SDQ_detect();
      if (read == SDQ_ERROR)
      {
        error();  
      }
      SDQ_writeByte(0xCC);                      // Skip ROM Command
      SDQ_writeByte(0x88);	                    // Read Control Command
      SDQ_writeByte(0x00);	                    // Write Address Low Byte
      SDQ_writeByte(0x00);	                    // Write Address High Byte
      read = SDQ_readByte();                    // Read CRC
      read = SDQ_readByte();                    // Read Data to Verify Write
      read = SDQ_readByte();                    // Read CRC
      
      // Read Silicon Revision Number
      SDQ_reset();
      read = SDQ_detect();
      if (read == SDQ_ERROR)
      {
        error();  
      }
      SDQ_writeByte(0xCC);                      // Skip ROM Command
      SDQ_writeByte(0x88);	                    // Read Control Command
      SDQ_writeByte(0x01);	                    // Write Address Low Byte
      SDQ_writeByte(0x00);	                    // Write Address High Byte
      read = SDQ_readByte();                    // Read CRC
      read = SDQ_readByte();                    // Read Data to Verify Write
      read = SDQ_readByte();                    // Read CRC
      
      // See if we can read the ID of the bq26100 that should be on the SDQ bus
      // Should be something like [F9 01 0F FD EB 6C 1A 89]
      SDQ_reset();                              // Send 160-bit Message to bq26100
      SDQ_detect();
      if (read == SDQ_ERROR)
      {
        error();  
      }
      SDQ_writeByte(0x33);                      // Read ID Command
      for (i = 0; i < DEVICEIDNUMBYTES; i++)
      {
        DeviceID[i] = SDQ_readByte();           // Read in each ID byte 
      }
    
      // Write 20 bytes (160 bits) into the Message registers starting at 0x0000
      SDQ_reset();                              // Send 160-bit Message to bq26100	   			
      read = SDQ_detect();                      // SDQ-based device connected?
      if (read == SDQ_ERROR)
      {
        error();  
      }
      SDQ_writeByte(0xCC);                      // Skip ROM Command
      SDQ_writeByte(0x22);	                    // Write Message Command
      SDQ_writeByte(0x00);	                    // Write Address Low Byte
      SDQ_writeByte(0x00);	                    // Write Address High Byte
      SDQ_writeByte(Message[0]);                // Write 1st byte of message
      read = SDQ_readByte();	            // Read CRC
      // CRC not calculated by MCU; results given by the bq26100 are ignored
      read = SDQ_readByte();                    // Read Data to Verify Write
      for (i = 1; i < RANDMESGNUMBYTES; i++)    // Write remaining bytes of message
      {
        SDQ_writeByte(Message[i]);
        read = SDQ_readByte();		    // Read CRC
        read = SDQ_readByte();		    // Read Data
      }
    
      // Write Control to set AUTH bit to initiate Authentication by bq26100
      SDQ_reset();
      read = SDQ_detect();
      if (read == SDQ_ERROR)
      {
        error();  
      }
      SDQ_writeByte(0xCC);                      // Skip ROM Command
      SDQ_writeByte(0x77);	                    // Write Control Command
      SDQ_writeByte(0x00);	                    // Write Address Low Byte
      SDQ_writeByte(0x00);	                    // Write Address High Byte
      SDQ_writeByte(0x01);	                    // Write AUTH Bit of CTRL Register
      read = SDQ_readByte();                    // Read CRC
      read = SDQ_readByte();                    // Read Data to Verify Write
    
      // Read Digest from bq26100
      SDQ_reset();
      read = SDQ_detect();
      if (read == SDQ_ERROR)
      {
        error();  
      }
      SDQ_writeByte(0xCC);                      // Skip ROM Command
      SDQ_writeByte(0xDD);	                    // Read Digest Command
      SDQ_writeByte(0x00);	                    // Write Address Low Byte
      SDQ_writeByte(0x00);	                    // Write Address High Byte
      read = SDQ_readByte();	            // Read CRC
      for (i = 0; i < DIGESTNUMBYTES; i++)      // Read Digest
      {
        Digest[i] = SDQ_readByte();
      }
      read = SDQ_readByte();                    // Read CRC of Digest
     
      // The 20 bytes of the digest returned by the bq26100 is arranged in 32-bit
      // words so that it can be compared with the results computed by the MCU
      Digest_32[4] = (UINT32)(Digest[ 0])*0x00000001 +
                     (UINT32)(Digest[ 1])*0x00000100 +
                     (UINT32)(Digest[ 2])*0x00010000 +
                     (UINT32)(Digest[ 3])*0x01000000;
      Digest_32[3] = (UINT32)(Digest[ 4])*0x00000001 +
                     (UINT32)(Digest[ 5])*0x00000100 +
                     (UINT32)(Digest[ 6])*0x00010000 +
                     (UINT32)(Digest[ 7])*0x01000000; 
      Digest_32[2] = (UINT32)(Digest[ 8])*0x00000001 +
                     (UINT32)(Digest[ 9])*0x00000100 +
                     (UINT32)(Digest[10])*0x00010000 +
                     (UINT32)(Digest[11])*0x01000000;
      Digest_32[1] = (UINT32)(Digest[12])*0x00000001 +
                     (UINT32)(Digest[13])*0x00000100 +
                     (UINT32)(Digest[14])*0x00010000 +
                     (UINT32)(Digest[15])*0x01000000;
      Digest_32[0] = (UINT32)(Digest[16])*0x00000001 +
                     (UINT32)(Digest[17])*0x00000100 +
                     (UINT32)(Digest[18])*0x00010000 +
                     (UINT32)(Digest[19])*0x01000000;
    
      // The results produced by the MCU and bq26100 must match for success
      if ( (Digest_32[0] == H[0]) && (Digest_32[1] == H[1]) &&
           (Digest_32[2] == H[2]) && (Digest_32[3] == H[3]) &&
           (Digest_32[4] == H[4]) )
      {
        STATUS_GOOD;                            // Output pin status = SUCCESS
      }
      else
      {
        STATUS_FAIL;                            // Output pin status = FAILURE
      }
    }