Tool/software: TI C/C++ Compiler
when compiled with TI compiler 16.9.6 in -Os mode the mbedTLS SHA-512 implementation produces incorrect results.
test code below is the excerpt that misbehaves - in particular, it looks like 64-bit shifts by more than 32 positions are not handled correctly.
#define GET_UINT64_BE(n,b,i) \ { \ (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ | ( (uint64_t) (b)[(i) + 1] << 48 ) \ | ( (uint64_t) (b)[(i) + 2] << 40 ) \ | ( (uint64_t) (b)[(i) + 3] << 32 ) \ | ( (uint64_t) (b)[(i) + 4] << 24 ) \ | ( (uint64_t) (b)[(i) + 5] << 16 ) \ | ( (uint64_t) (b)[(i) + 6] << 8 ) \ | ( (uint64_t) (b)[(i) + 7] ); \ } static void test64(void) { uint64_t w[2] = {0, 0}; int i; static const uint8_t td[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; for (i = 0; i < 2; i++) { GET_UINT64_BE(w[i], td, i << 3); } for (i = 0; i < sizeof(w); i++) { printf("%02x ", ((uint8_t *) w)[i]); } printf("\n"); }
when run, it produces the following output:
07 06 05 04 03 00 00 00 0f 0e 0d 0c 0b 00 00 00
note that top 3 bytes in the uint64_ts are zeroes, so it looks like shifts by 40, 48 and 56 result in 0 in the | operator above.
this is the assembler code generated by the compiler:
0103eaf4 <test64>: 103eaf4: b5f0 push {r4, r5, r6, r7, lr} 103eaf6: 2100 movs r1, #0 103eaf8: 2210 movs r2, #16 103eafa: f1ad 0d14 sub.w sp, sp, #20 103eafe: 4668 mov r0, sp 103eb00: f005 fc3e bl 1044380 <memset> 103eb04: 4c24 ldr r4, [pc, #144] ; (103eb98 <test64+0xa4>) 103eb06: 466d mov r5, sp 103eb08: 2300 movs r3, #0 103eb0a: 2702 movs r7, #2 103eb0c: 78e6 ldrb r6, [r4, #3] 103eb0e: 78a0 ldrb r0, [r4, #2] 103eb10: 17f1 asrs r1, r6, #31 103eb12: 4318 orrs r0, r3 103eb14: 0202 lsls r2, r0, #8 103eb16: ea46 0003 orr.w r0, r6, r3 103eb1a: 4311 orrs r1, r2 103eb1c: 0e02 lsrs r2, r0, #24 103eb1e: 0206 lsls r6, r0, #8 103eb20: 7920 ldrb r0, [r4, #4] 103eb22: 0209 lsls r1, r1, #8 103eb24: 4311 orrs r1, r2 103eb26: 17c2 asrs r2, r0, #31 103eb28: 430a orrs r2, r1 103eb2a: 4330 orrs r0, r6 103eb2c: 0211 lsls r1, r2, #8 103eb2e: 0206 lsls r6, r0, #8 103eb30: 0e02 lsrs r2, r0, #24 103eb32: 7960 ldrb r0, [r4, #5] 103eb34: 4311 orrs r1, r2 103eb36: 17c2 asrs r2, r0, #31 103eb38: 430a orrs r2, r1 103eb3a: 4330 orrs r0, r6 103eb3c: 0211 lsls r1, r2, #8 103eb3e: 0206 lsls r6, r0, #8 103eb40: 0e02 lsrs r2, r0, #24 103eb42: 79a0 ldrb r0, [r4, #6] 103eb44: 4311 orrs r1, r2 103eb46: 17c2 asrs r2, r0, #31 103eb48: 430a orrs r2, r1 103eb4a: 4330 orrs r0, r6 103eb4c: 0211 lsls r1, r2, #8 103eb4e: 0206 lsls r6, r0, #8 103eb50: 0e02 lsrs r2, r0, #24 103eb52: 79e0 ldrb r0, [r4, #7] 103eb54: 1e7f subs r7, r7, #1 103eb56: ea41 0102 orr.w r1, r1, r2 103eb5a: ea4f 72e0 mov.w r2, r0, asr #31 103eb5e: f104 0408 add.w r4, r4, #8 103eb62: ea42 0101 orr.w r1, r2, r1 103eb66: ea40 0006 orr.w r0, r0, r6 103eb6a: c503 stmia r5!, {r0, r1} 103eb6c: d1ce bne.n 103eb0c <test64+0x18> 103eb6e: 2410 movs r4, #16 103eb70: 466d mov r5, sp 103eb72: f815 1b01 ldrb.w r1, [r5], #1 103eb76: a005 add r0, pc, #20 ; (adr r0, 103eb8c <test64+0x98>) 103eb78: f006 ffd0 bl 1045b1c <printf> 103eb7c: 1e64 subs r4, r4, #1 103eb7e: d1f8 bne.n 103eb72 <test64+0x7e> 103eb80: a004 add r0, pc, #16 ; (adr r0, 103eb94 <test64+0xa0>) 103eb82: f006 ffcb bl 1045b1c <printf> 103eb86: b005 add sp, #20 103eb88: bdf0 pop {r4, r5, r6, r7, pc} 103eb8a: 46c0 nop ; (mov r8, r8) 103eb8c: 78323025 .word 0x78323025 103eb90: 46c00020 .word 0x46c00020 103eb94: 46c0000a .word 0x46c0000a 103eb98: 01059282 .word 0x01059282