David Jung / Mbed OS MAX86140_Authenication_SHA256_test

Dependencies:   MAX8614X USBDevice max32630hsp_test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /**********************************************************************
00002 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
00003 *
00004 * Permission is hereby granted, free of charge, to any person obtaining a
00005 * copy of this software and associated documentation files (the "Software"),
00006 * to deal in the Software without restriction, including without limitation
00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 * and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included
00012 * in all copies or substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020 * OTHER DEALINGS IN THE SOFTWARE.
00021 *
00022 * Except as contained in this notice, the name of Maxim Integrated
00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024 * Products, Inc. Branding Policy.
00025 *
00026 * The mere transfer of this software does not imply any licenses
00027 * of trade secrets, proprietary technology, copyrights, patents,
00028 * trademarks, maskwork rights, or any other form of intellectual
00029 * property whatsoever. Maxim Integrated Products, Inc. retains all
00030 * ownership rights.
00031 **********************************************************************/
00032 
00033 
00034 #include "mbed.h"
00035 //#include "max32630fthr.h"
00036 #include "max32630hsp.h"
00037 #include "MAX8614X.h"
00038 #include "USBSerial.h"
00039 
00040 //#define DEBUG_ON 1
00041 
00042 void executeSha256(MAX8614X &m, uint32_t *challenge, unsigned int challengeLen, bool romID, uint32_t *response);
00043 bool isTheChipAuthenicated(uint32_t *expectedResponse, uint32_t *chipResponse);
00044 
00045 #define RESPONSE_LEN32 8
00046 
00047 MAX32630HSP icarus(MAX32630HSP::VIO_1V8);
00048 //    MAX32630FTHR mbed_board(MAX32630FTHR::VIO_1V8);
00049 SPI spi(P5_1, P5_2, P5_0); /* mosi, miso, sclk */
00050 DigitalOut cs(P5_3);
00051 PinName interrupt_pin = P3_2;
00052 // Virtual serial port over USB
00053 USBSerial microUSB; 
00054 
00055 DigitalOut rLED(LED1);
00056 DigitalOut gLED(LED2);
00057 DigitalOut bLED(LED3);
00058 // main() runs in its own thread in the OS
00059 // (note the calls to Thread::wait below for delays)
00060 /**
00061 * @brief Sample main program for SHA256 Authenication using the MAX86140
00062 * @version 1.0000.0
00063 *
00064 * @details Sample main program for MAX86140 authenication.
00065 * The prints are sent to the terminal window (9600, 8n1).
00066 * The program issues challenges to the MAX86140 SHA256 athenicator.
00067 * The responses are compared to the expected responses.
00068 * To run the program, drag and drop the .bin file into the 
00069 * DAPLINK folder. After it finishes flashing, cycle the power or 
00070 * reset the board.
00071 */
00072 
00073 int main()
00074 {
00075     #define CHALLENGE32_LEN 5
00076     uint32_t challenge_A[CHALLENGE32_LEN] = {  // 160 bit, no ROM
00077         0x00000001,
00078         0x00000000,
00079         0x00000000,
00080         0x00000000,
00081         0x00000000
00082     };
00083     uint32_t expectedResponse_A_romID[RESPONSE_LEN32] = {  // 160 bit, no ROM
00084         0xf987d79a,
00085         0xeb778ec7,
00086         0x33861bc8,
00087         0x745d4082,
00088         0x921e02fe,
00089         0x727d93c8,
00090         0x218e53ee,
00091         0x904e0c6b
00092     };
00093     uint32_t challenge_1[CHALLENGE32_LEN] = {  // 160 bit
00094         0x5e813524,
00095         0x5663d609,
00096         0x998d7b0d,
00097         0x52128465,
00098         0xcd0de301
00099     };
00100     uint32_t expectedResponse_1_romID[RESPONSE_LEN32] = {  // 160 bit
00101         0xfe3f805f,
00102         0x0af066bc,
00103         0xda0f55e2,
00104         0x0020ac16,
00105         0x13fa3406,
00106         0x59d0e5ae,
00107         0x79def309,
00108         0x685981a3
00109     };
00110 
00111     uint32_t challenge_2[CHALLENGE32_LEN] = {  // 160 bit, no ROM
00112         0xd2aa84c5,
00113         0x7277f7e5,
00114         0xdb8fd612,
00115         0x96ce69f2,
00116         0x4ec57ae8
00117     };
00118 
00119     uint32_t expectedResponse_2_noRomID[RESPONSE_LEN32] = {  // 160 bit, no ROM
00120         0x1a7135a2,
00121         0x51b99ca8,
00122         0xbdd9245e,
00123         0xb9c8e758,
00124         0x770ec1c4,
00125         0x474ffcc7,
00126         0x828afe4d,
00127         0x9cb3de6d
00128     };
00129     uint32_t challenge_3[CHALLENGE32_LEN] = {  // 160 bit
00130         0x21202280,
00131         0xcc9d45aa,
00132         0xb8133e96,
00133         0xd653380d,
00134         0x2ad5dd6b
00135     };
00136     uint32_t expectedResponse_3_romID[RESPONSE_LEN32] = {  // 160 bit
00137         0xe7750b8d,
00138         0xe29d9279,
00139         0x7cdc7053,
00140         0xa9f92519,
00141         0xa1e59d93,
00142         0x19cd930d,
00143         0xfb0fc974,
00144         0x2da0781e
00145     };
00146     uint32_t challenge_4[CHALLENGE32_LEN] = {  // 160 bit, no ROM
00147         0x4c3c0aca,
00148         0x618abdf2,
00149         0x34d8b341,
00150         0x1289f378,
00151         0x65b60deb
00152     };
00153     uint32_t expectedResponse_4_noRomID[RESPONSE_LEN32] = {  // 160 bit, no ROM
00154         0xae740f91,
00155         0x8d6f2d58,
00156         0x7486b0ba,
00157         0xe9a84580,
00158         0xfe9ce593,
00159         0x58d66c7d,
00160         0xc993d165,
00161         0xe5ae5983
00162     };
00163 
00164     uint32_t chip_response[RESPONSE_LEN32];
00165     bool valid = 0;
00166 
00167     rLED = LED_OFF;
00168     gLED = LED_ON;
00169     bLED = LED_OFF;
00170 
00171     printf("\r\n\rmax86140 authenication software\r\n");
00172     MAX8614X m(spi,cs,interrupt_pin);
00173     m.init();
00174 
00175     //● Compare MAC from MAX86140 wth Host's precalculated MAC.
00176     executeSha256(m, challenge_A, CHALLENGE32_LEN, 1, chip_response);
00177     //● Check PASS or FAIL.
00178     valid = isTheChipAuthenicated(chip_response, expectedResponse_A_romID);
00179     if (valid)
00180         printf("\r\n             Challenge A passed\r\n\r\n");
00181     else
00182         printf("\r\n             Challenge A failed\r\n\r\n");
00183 
00184     //● Compare MAC from MAX86140 wth Host's precalculated MAC.
00185     executeSha256(m, challenge_1, CHALLENGE32_LEN, 1, chip_response);
00186     //● Check PASS or FAIL.
00187     valid = isTheChipAuthenicated(chip_response, expectedResponse_1_romID);
00188     if (valid)
00189         printf("\r\n             Challenge 1 passed\r\n\r\n");
00190     else
00191         printf("\r\n             Challenge 1 failed\r\n\r\n");
00192 
00193     executeSha256(m, challenge_2, CHALLENGE32_LEN, 0, chip_response);
00194     valid = isTheChipAuthenicated(chip_response, expectedResponse_2_noRomID);
00195     if (valid)
00196         printf("\r\n             Challenge 2 passed\r\n\r\n");
00197     else
00198         printf("\r\n             Challenge 2 failed\r\n\r\n");
00199 
00200     executeSha256(m, challenge_3, CHALLENGE32_LEN, 1, chip_response);
00201     valid = isTheChipAuthenicated(chip_response, expectedResponse_3_romID);
00202     if (valid)
00203         printf("\r\n             Challenge 3 passed\r\n\r\n");
00204     else
00205         printf("\r\n             Challenge 3 failed\r\n\r\n");
00206 
00207     executeSha256(m, challenge_4, CHALLENGE32_LEN, 0, chip_response);
00208     valid = isTheChipAuthenicated(chip_response, expectedResponse_4_noRomID);
00209     if (valid)
00210         printf("\r\n             Challenge 4 passed\r\n\r\n");
00211     else
00212         printf("\r\n             Challenge 4 failed\r\n\r\n");
00213 
00214     //● Disable SHA_EN bit ( Write 0 to SHA_EN bit).     
00215     m.writeRegister(MAX8614X::MAX8614X_SHA_CFG_REG, 0);
00216     while(1) {
00217         gLED = !gLED;
00218         wait(1.0);
00219     }
00220 }
00221 
00222 bool isTheChipAuthenicated(uint32_t *expectedResponse, uint32_t * chipResponse)
00223 {
00224     int i;
00225     for (i = 0; i < RESPONSE_LEN32; i++) {
00226         if (expectedResponse[i] != chipResponse[i])
00227             return 0;
00228     }
00229     return 1;
00230 }
00231 
00232 void transformData(uint8_t *inData, uint8_t *outData, unsigned int challengeLen)
00233 {
00234     int i, j, k;
00235     k = 0;
00236     for (i = 0; i < (challengeLen/4); i++) {
00237         for (j = 3; j >= 0; j--) {
00238             outData[j+(i*4)] = inData[k];
00239             k++;
00240         }
00241     }
00242 }
00243 void executeSha256(MAX8614X &m, uint32_t *challenge, unsigned int challengeLen, bool romID, uint32_t *response)
00244 {
00245     int i, j, k;
00246     uint8_t macData[256];
00247     uint8_t xData[256];
00248     uint32_t x32Data[64];
00249     uint32_t tmpData;
00250     const unsigned int responseLen32 = 8;
00251     uint8_t data[5];
00252 
00253     //● Enable SHA_DONE Interrupt
00254     m.writeRegister(MAX8614X::MAX8614X_INT_ENABLE2_REG, MAX8614X::MAX8614X_IE_SHA_DONE_EN);
00255 
00256     m.writeRegister(MAX8614X::MAX8614X_INT_ENABLE1_REG, 0);  // Disable all other interrupts
00257 
00258     //- Enable SHA_EN bit.
00259     m.writeRegister(MAX8614X::MAX8614X_SHA_CFG_REG,MAX8614X::MAX8614X_SHACFG_SHA_EN);
00260 
00261     //● Write 160-bit random challenge value to RAM using registers MEM_IDX and MEM_DATA.
00262     // Enable Memory Write, Select Bank 0, address 0x00 to 0xFF
00263     m.writeRegister(MAX8614X::MAX8614X_MEMORY_CONTROL_REG, MAX8614X::MAX8614X_MEMCNTRL_WR_EN_MASK | MAX8614X::MAX8614X_MEMCNTRL_BANK0_MASK);
00264 
00265     for (i = 0; i < 5; i++) {
00266         x32Data[i] = challenge[i];
00267         for (j = 0; j <= 3; j++) {
00268             xData[(i*4)+j] = x32Data[i] & 0xFF;
00269             x32Data[i] = x32Data[i] >> 8;
00270             k++;
00271         }
00272     }
00273 
00274 #ifdef DEBUG_ON
00275     printf("\r\n Raw Input Data\r\n\r\n");
00276     for (i = 0; i < challengeLen; i++) {
00277         printf("%08x\r\n", challenge[i]);
00278     }
00279     printf("\r\n");
00280 #endif
00281 
00282     //transformData(challenge, xData, challengeLen);
00283 
00284 #ifdef DEBUG_ON
00285     printf("\r\n Transformed Input Data\r\n\r\n");
00286     for (i = 0; i < challengeLen*4; i++) {
00287         if (!(i % 4))
00288             printf("\r\n ");
00289         printf("%02x", xData[i]);
00290     }
00291         printf("\r\n ");
00292 #endif
00293         
00294     for (i = 0; i < (challengeLen*4); i++) {
00295         m.writeRegister(MAX8614X::MAX8614X_MEMORY_INDEX_REG, i);
00296         m.writeRegister(MAX8614X::MAX8614X_MEMORY_DATA_REG, xData[i]);
00297     //}
00298   }
00299 
00300     // The message block consists of a 160-bit secret, a 160-bit challenge and 192 bits of constant data. Optionally, the 64-bit
00301     // ROM ID replaces 64 of the 192 bits of constant data used in the hash operation. 16 bits out of the 160-bit secret and 16
00302     // bits of ROM ID are programmable–8 bits each in metal and 8 bits each in OTP bits
00303     //● Write command, with ROM ID (0x35) or without ROM ID (0x36), to SHA_CMD register
00304     if (romID) {
00305         m.writeRegister(MAX8614X::MAX8614X_SHA_CMD_REG, MAX8614X::MAX8614X_SHACMD_MAC_ROM_ID);
00306     }
00307     else
00308     {
00309         m.writeRegister(MAX8614X::MAX8614X_SHA_CMD_REG,MAX8614X::MAX8614X_SHACMD_MAC_NO_ROM_ID);
00310     }
00311 
00312     m.readRegister(MAX8614X::MAX8614X_SHA_CMD_REG, data, 1);
00313     //● Write 1 to SHA_START and 1 to SHA_EN bit.
00314     m.writeRegister(MAX8614X::MAX8614X_SHA_CFG_REG,MAX8614X::MAX8614X_SHACFG_SHA_EN | MAX8614X::MAX8614X_SHACFG_SHA_START);
00315     
00316     //● Wait for SHA_DONE.
00317     data[0] = 0;
00318     k = 0;
00319     while(!data[0] && k < 100) {
00320         m.readRegister(MAX8614X::MAX8614X_INT_STATUS2_REG, data, 1);
00321         k++;
00322     }
00323     // ● Read 256 MAC value from RAM using registers MEM_IDX and MEM_DATA.
00324 #ifdef DEBUG_ON
00325     printf("\r\n Raw Output\r\n\r\n");
00326 #endif
00327     for (i = 64; i < 64+32; i++) {
00328 #ifdef DEBUG_ON
00329         if (!(i % 4))
00330             printf("\r\n ");
00331 #endif
00332         m.writeRegister(MAX8614X::MAX8614X_MEMORY_INDEX_REG, i);
00333         m.readRegister(MAX8614X::MAX8614X_MEMORY_DATA_REG, data, 1);
00334         xData[i-64] = data[0];
00335 #ifdef DEBUG_ON
00336         printf("%02x", data[0]);
00337 #endif
00338     } 
00339 #ifdef DEBUG_ON
00340     printf("%\r\n");
00341 #endif
00342 
00343     transformData(xData,macData, 32);
00344 #ifdef DEBUG_ON
00345     printf("\r\n Formatted Response\r\n\r\n");
00346     for (i = 0; i < responseLen32*4; i++) {
00347         if (!(i % 4))
00348             printf("\r\n ");
00349         printf("%02x", macData[i]);
00350     }
00351     printf("\r\n\r\n");
00352     
00353 #endif
00354      // transform data to Little-Endian
00355     k = 0;
00356     for (i = 0; i < (responseLen32); i++) {
00357         x32Data[i] = 0;
00358         for (j = 3; j >= 0; j--) {
00359             x32Data[i] = x32Data[i] << 8;
00360             x32Data[i] |= macData[k] & 0xFF;
00361             k++;
00362         }
00363     }
00364 
00365 #ifdef DEBUG_ON
00366     printf("\r\n Formatted Response\r\n\r\n");
00367 #endif
00368     for (i = 0; i < responseLen32; i++) {
00369 #ifdef DEBUG_ON
00370         printf(" %08X \r\n",x32Data[i]);
00371 #endif
00372         response[i] = x32Data[i];
00373     }
00374 }