60.4.9.4 SHA Register Endianness
In Arm processor-based products, the system bus and processors manipulate data in little-endian form. The SHA interface requires little-endian format words. However, in accordance with the protocol of the FIPS 180 specification, data is collected, processed and stored by the SHA algorithm in big-endian form.
The following example illustrates how to configure the SHA:
If the first 64 bits of a message (according to FIPS 180, i.e., big-endian format) to be processed is 0xcafedeca_01234567, then the SHA_IDATAR0 and SHA_IDATAR1 registers must be written with the following pattern:
- SHA_IDATAR0 = 0xcadefeca
- SHA_IDATAR1 = 0x67452301
In a little-endian system, the message (according to FIPS 180) starting with pattern 0xcafedeca_01234567 is stored into memory as follows:
- 0xca stored at initial offset (for example 0x00),
- then 0xfe stored at initial offset + 1 (i.e., 0x01),
- 0xde stored at initial offset + 2 (i.e., 0x02),
- 0xca stored at initial offset + 3 (i.e., 0x03).
If the message is received through a serial-to-parallel communication channel, the first received character is 0xca and it is stored at the first memory location (initial offset). The second byte, 0xfe, is stored at initial offset + 1.
When reading on a 32-bit little-endian system bus, the first word read back from system memory is 0xcadefeca.
When the SHA_IODATARx registers are read, the hash result is organized in little-endian format, allowing system memory storage in the same format as the message.
Taking an example from the FIPS 180 specification Appendix B.1, the endian conversion can be observed.
For this example, the 512-bit message is:
0x61626380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018
and the expected SHA-256 result is:
0xba7816bf_8f01cfea_414140de_5dae2223_b00361a3_96177a9c_b410ff61_f20015ad
If the message has not already been stored in the system memory, the first step is to convert the input message to little-endian before writing to the SHA_IDATARx registers. This would result in a write of:
SHA_IDATAR0 = 0x80636261...... SHA_IDATAR15 = 0x18000000
The data in the output message digest registers, SHA_IODATARx, contain SHA_IODATAR0 = 0xbf1678ba... SHA_IODATAR7 = 0xad1500f2 which is the little-endian format of 0xba7816bf,..., 0xf20015ad.
Reading SHA_IODATAR0 to SHA_IODATAR1 and storing into a little-endian memory system forces hash results to be stored in the same format as the message.
When the output message is read, the user can convert back to big-endian for a resulting message value of:
0xba7816bf_8f01cfea_414140de_5dae2223_b00361a3_96177a9c_b410ff61_f20015ad