ATSHA204a - Calculate the expected response

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am working with the ATSHA204A - CryptoAuthentication chip. The chip performs SHA256 Hash Algorithm with Message Authentication Code (MAC). I am able to hash the known key and create a 256-bit digest with the ATSHA204a. At the same time, my code needs to calculate the expected response.

 

I am generating the digest on the ATSHA204a with the following commands:

 

Nonce:
Mode:       0x03
NumIn:         0x0000A1AC57FF404E45D4D401BD0ED3C673D3B7B82D85D9F313B55EDA3D940000
MAC:
Mode:        0x00
SlotID:       0x04 // slot 4 is the location of the key
Challenge:  0xAB97FC3D408D5510565C511CD08603DB242707926B13F17F6D5B5BE14B5F2C50

 

Response (0x) :
4B 19 E2 5E 17 DC E9 15 AB 3C 27 E3 AC 80 08 AC 09 87 CC 36 FA 25 B0 A9 D7 5B BE 17 9E 39 25 35

In order to generate the expected response on the software side, the datasheet states (8.5.11 MAC Command) I need to hash the following with SHA-256:

 

 

The buffer to hash is 88 bytes. My key, challenge and required data per 8.5.11 MAC Command:

 

uint8_t challenge[32] = {
		0xAB,0x97,0xFC,0x3D,
		0x40,0x8D,0x55,0x10,
		0x56,0x5C,0x51,0x1C,
		0xD0,0x86,0x03,0xDB,
		0x24,0x27,0x07,0x92,
		0x6B,0x13,0xF1,0x7F,
		0x6D,0x5B,0x5B,0xE1,
		0x4B,0x5F,0x2C,0x50
	};
	uint8_t mykey[32] = {
	    0x08,0xe6,0xe6,0x93,
	    0x69,0x4a,0x4c,0xd7,
	    0x84,0xf2,0x09,0xb6,
	    0x74,0x6d,0xea,0x1e,
	    0x8e,0x1d,0xa0,0xa8,
	    0x21,0xaa,0x4f,0x59,
	    0xb0,0x63,0xe7,0x80,
	    0x93,0x69,0x2f,0x7c
	 };

 

uint8_t request[88] = { '\0'};
memcpy(request, &mykey, 32); // key
memcpy(&request[32], &tempKey, 32); // temp_key

request[64] = 0x08; // OpCode MAC
request[65] = 0x00; // Mode
request[66] = 0x00; // slot number for key upper
request[67] = 0x04; // slot number for key lower - slot 0 is used

request[68] = 0x00;
request[69] = 0x00;
request[70] = 0x00;
request[71] = 0x00;
request[72] = 0x00;
request[73] = 0x00;
request[74] = 0x00;
request[75] = 0x00;
request[76] = 0x00;
request[77] = 0x00;
request[78] = 0x00;

request[79] = 0xEE; // SN<8>

request[80] = 0x00;
request[81] = 0x00;
request[82] = 0x00;
request[83] = 0x00;

request[84] = 0x01; // SN<0:1>
request[85] = 0x23; // SN<0:1>

request[86] = 0x00;
request[87] = 0x00;

This creates an 88 byte array to be hashed:

 

 

request[88] = {
    0x08,0xE6,0xE6,0x93,0x69,0x4A,0x4C,0xD7,0x84,0xF2,
    0x09,0xB6,0x74,0x6D,0xEA,0x1E,0x8E,0x1D,0xA0,0xA8,
    0x21,0xAA,0x4F,0x59,0xB0,0x63,0xE7,0x80,0x93,0x69,
    0x2F,0x7C,0x00,0x00,0xA1,0xAC,0x57,0xFF,0x40,0x4E,
    0x45,0xD4,0xD4,0x01,0xBD,0x0E,0xD3,0xC6,0x73,0xD3,
    0xB7,0xB8,0x2D,0x85,0xD9,0xF3,0x13,0xB5,0x5E,0xDA,
    0x3D,0x94,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,
    0x00,0x00,0x00,0x00,0x01,0x23,0x00,0x00};

To test my request buffer, I have hashed this with the Atmel ACES program and online. Both return a SHA256 Digest:

 

0x783100d84a6eca96651e99dc358d65aa164fd664da115e1467b64e66a5a3514c

Which doesn't match with the ATSHA204a generated. I am not sure what I am doing wrong. Any help is greatly appreciated.

This topic has a solution.

"When all else fails, read the directions"

Last Edited: Sat. Jul 7, 2018 - 05:51 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After a lot of reading, the devil is in the details. To do a simple fixed challenge and validate the digest, the configuration for the slot (key) needs to have the CheckOnly Flags set to 0. The below solution, uses the CryptopAuthLib.  I am using the factory default keys that came with the ATSHA204a. The Config zone is locked or this wont work.

 

uint8_t key08[32] = {0x88,0x88,0xC6,0x2A,0xFE,0x1F,0x82,0xD4,0xE0,0x85,0x85,0x34,0x4D,0x77,0xB8,0x9D,0xEC,0x36,0xF2,0x06,0x27,0xE4,0xF0,0xCF,0x03,0x0E,0x27,0xB8,0xEE,0xE3,0x88,0x88};

test_atsha204_fixed_challenge(0x08, key08);

 

void test_atsha204_fixed_challenge(uint8_t slot, uint8_t secretKey[32]){
	ATCA_STATUS status;
	uint8_t digest[32]= { '\0'};
	uint8_t sw_digest[32]= { '\0'};

	uint8_t challenge[32] = {
		0xAB,0x97,0xFC,0x3D,
		0x40,0x8D,0x55,0x10,
		0x56,0x5C,0x51,0x1C,
		0xD0,0x86,0x03,0xDB,
		0x24,0x27,0x07,0x92,
		0x6B,0x13,0xF1,0x7F,
		0x6D,0x5B,0x5B,0xE1,
		0x4B,0x5F,0x2C,0x50
	};

	/* Hardware*/
	status = atcab_init(&cfg_atsha204a_i2c_default);
	if(status != ATCA_SUCCESS){
		printf("Unable to init crypto\n\r");
	}
	printf("\n\rSerial Number\n\r");
	status = atcab_read_serial_number(serialNumber);
	for(int i = 0; i < 9;i++){
		printf("0x%02X ", serialNumber[i]);
	}
	printf("\n\r");

	status = atcab_mac(0x00, 0x00 + slot, challenge, digest);
	if (status != ATCA_SUCCESS)
	{
		printf("Unable to create digest!!\n\r");
	}
	printf("\n\rDigest from ATSHA204a\n\r");
	for(uint8_t i = 0; i < sizeof digest;i++){
		printf("0x%X ", digest[i]);
	}
	uint8_t request[88] = { '\0'};
	memset(request, 0, sizeof request); // set all with 0

	memcpy(request, secretKey, 32);
	memcpy(&request[32], &challenge, 32);

	request[64] = 0x08; //opcode
	request[65] = 0x00; //param1mac
	request[66] = slot; // Key Slot ID
	request[67] = 0x00; //param2mac always 00

	request[68] = 0x00;
	request[69] = 0x00;
	request[70] = 0x00;
	request[71] = 0x00;
	request[72] = 0x00;
	request[73] = 0x00;
	request[74] = 0x00;
	request[75] = 0x00;
	request[76] = 0x00;
	request[77] = 0x00;
	request[78] = 0x00;
	request[79] = serialNumber[8]; //0xEE; // SN<8>

	request[80] = 0x00;
	request[81] = 0x00;
	request[82] = 0x00;
	request[83] = 0x00;

	request[84] = serialNumber[0]; // 0x01; // SN<0:1>
	request[85] = serialNumber[1];  //0x23; // SN<0:1>

	request[86] = 0x00;
	request[87] = 0x00;

	status = atcac_sw_sha2_256(request, 88, sw_digest);
	if (status != ATCA_SUCCESS)
	{
		printf("Unable to create digest!!\n\r");
	}
	printf("\n\r My SHA Digest \n\r");
	for(uint8_t i = 0; i < sizeof sw_digest;i++){
		printf("0x%X ", sw_digest[i]);
	}

	compare_digests(digest, sw_digest, sizeof(sw_digest));

}
void compare_digests(uint8_t *dig1,uint8_t *dig2, int len){

	// compare hashes
	int n=memcmp ( dig1, dig2, len );

	if (n == 0){
		printf("\n\rDigests are the same!\n\r");
	} else {
		printf("\n\rDigests are the NOT the same!\n\r");
	}
}

 

 

 

"When all else fails, read the directions"

Last Edited: Wed. Sep 19, 2018 - 12:27 AM