Skip to content

Commit e89942d

Browse files
committed
crypto: it51xxx: Fix SHA-256 padding length field to 64-bi
The SHA-256 standard (FIPS 180-4) requires the total message length (L) in bits to be appended as a **64-bit big-endian integer**. The previous implementation incorrectly calculated and wrote only the lower **32 bits** of the length field (to W[15]), implicitly assuming the upper 32 bits (W[14]) were correctly zeroed. This commit updates `it51xxx_hash_handler()` to explicitly calculate the length using `uint64_t` and writes both the MSB (W[14]) and LSB (W[15]) words in big-endian format. This ensures standard compliance and correct hashing for all message lengths. Signed-off-by: Badr Bacem KAABIA <[email protected]>
1 parent 3af17bf commit e89942d

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

drivers/crypto/crypto_it51xxx_sha.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,17 @@ static int it51xxx_hash_handler(struct hash_ctx *ctx, struct hash_pkt *pkt, bool
183183
}
184184

185185
/*
186-
* Since input data (big-endian) are copied 1byte by 1byte to
187-
* it51xxx memory (little-endian), so the bit length needs to
188-
* be transformed into big-endian format and then write to memory.
186+
* SHA-256 requires the message length (in bits) as a 64-bit big-endian
187+
* integer in the final 8 bytes (words 14 and 15). The message is stored
188+
* in little-endian memory, so conversion is necessary.
189189
*/
190-
chip_ctx.w_sha[15] = sys_cpu_to_be32(chip_ctx.total_len * 8);
190+
uint64_t bit_len = (uint64_t)chip_ctx.total_len * 8;
191+
192+
// Word 14: Most Significant 32 bits
193+
chip_ctx.w_sha[14] = sys_cpu_to_be32((uint32_t)(bit_len >> 32));
194+
195+
// Word 15: Least Significant 32 bits
196+
chip_ctx.w_sha[15] = sys_cpu_to_be32((uint32_t)(bit_len & 0xFFFFFFFFUL));
191197

192198
/* HW automatically load 64Bytes data from DLM */
193199
sys_write8(IT51XXX_SHAEXEC_64_BYTE, IT51XXX_SHAECR);

drivers/crypto/crypto_it8xxx2_sha.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,20 @@ static int it8xxx2_hash_handler(struct hash_ctx *ctx, struct hash_pkt *pkt,
157157
memset(&chip_ctx.w_input[chip_ctx.w_input_index],
158158
0, SHA_SHA256_BLOCK_LEN - chip_ctx.w_input_index);
159159
}
160-
chip_ctx.w_sha[15] = sys_cpu_to_be32(chip_ctx.total_len * 8);
160+
161+
/*
162+
* SHA-256 requires the message length (in bits) as a 64-bit big-endian
163+
* integer in the final 8 bytes (words 14 and 15). The message is stored
164+
* in little-endian memory, so conversion is necessary.
165+
*/
166+
uint64_t bit_len = (uint64_t)chip_ctx.total_len * 8;
167+
168+
// Word 14: Most Significant 32 bits
169+
chip_ctx.w_sha[14] = sys_cpu_to_be32((uint32_t)(bit_len >> 32));
170+
171+
// Word 15: Least Significant 32 bits
172+
chip_ctx.w_sha[15] = sys_cpu_to_be32((uint32_t)(bit_len & 0xFFFFFFFFUL));
173+
161174
it8xxx2_sha256_module_calculation();
162175

163176
for (int i = 0; i < SHA_SHA256_HASH_LEN_WORDS; i++) {

drivers/crypto/crypto_it8xxx2_sha_v2.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,17 @@ static int it8xxx2_hash_handler(struct hash_ctx *ctx, struct hash_pkt *pkt,
227227
}
228228

229229
/*
230-
* Since input data (big-endian) are copied 1byte by 1byte to
231-
* it8xxx2 memory (little-endian), so the bit length needs to
232-
* be transformed into big-endian format and then write to memory.
230+
* SHA-256 requires the message length (in bits) as a 64-bit big-endian
231+
* integer in the final 8 bytes (words 14 and 15). The message is stored
232+
* in little-endian memory, so conversion is necessary.
233233
*/
234-
chip_ctx.w_sha[15] = sys_cpu_to_be32(chip_ctx.total_len * 8);
234+
uint64_t bit_len = (uint64_t)chip_ctx.total_len * 8;
235+
236+
// Word 14: Most Significant 32 bits
237+
chip_ctx.w_sha[14] = sys_cpu_to_be32((uint32_t)(bit_len >> 32));
238+
239+
// Word 15: Least Significant 32 bits
240+
chip_ctx.w_sha[15] = sys_cpu_to_be32((uint32_t)(bit_len & 0xFFFFFFFFUL));
235241

236242
/* HW automatically load 64Bytes data from DLM */
237243
sys_write8(IT8XXX2_SHAEXEC_64Byte, IT8XXX2_SHA_REGS_BASE + IT8XXX2_REG_SHAECR);

0 commit comments

Comments
 (0)