What | Removed | Added |
---|---|---|
CC | matz@suse.com, yousaf.kaukab@suse.com |
ecdsa_set_pub_key() is making a u64 pointer at 1 byte offset of the key. const unsigned char *d = key; const u64 *digits = (const u64 *)&d[1]; So digits will mostly be unaligned. ecc_swap_digits() is then using ldm instruction on this unaligned pointer which is causing the exception. There are two instances of ecc_swap_digits(). First instance is implemented by two ldr instructions. As ldr can handle unaligned addresses, it works. The second instance is implemented by an ldm instruction which can't handle unaligned addresses and causes the exception. Here is the disassembly of the code: /* First instance */ ../crypto/ecc.h: 54 for (i = 0; i < ndigits; i++) 0xc07c26f0 <+132>: cmp r3, #0 0xc07c26f4 <+136>: beq 0xc07c276c <ecdsa_set_pub_key+256> 0xc07c26f8 <+140>: add r1, r5, #1 0xc07c26fc <+144>: sub r6, r3, #1 0xc07c2700 <+148>: lsl r5, r3, #3 0xc07c2704 <+152>: add r12, r4, #72 ; 0x48 0xc07c2708 <+156>: add r3, r1, r3, lsl #3 55 out[i] = be64_to_cpu(src[ndigits - 1 - i]); 0xc07c270c <+160>: ldr r2, [r3, #-8]! //<== First load == 0xc07c2710 <+164>: ldr r0, [r3, #4] //<== Second load == 0xc07c2714 <+168>: rev r2, r2 0xc07c2718 <+172>: rev r0, r0 0xc07c271c <+176>: str r0, [r12, #8]! 0xc07c2720 <+180>: cmp r3, r1 0xc07c2724 <+184>: str r2, [r12, #4] /* Second instance */ ../crypto/ecdsa.c: 246 ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits); 0xc07c272c <+192>: ldr r0, [r4, #212] ; 0xd4 ../crypto/ecc.h: 54 for (i = 0; i < ndigits; i++) 0xc07c2730 <+196>: bic lr, lr, #7 0xc07c2734 <+200>: add lr, lr, r6, lsl #3 0xc07c2738 <+204>: sub r5, r5, #8 0xc07c273c <+208>: sub r2, r0, #8 0xc07c2740 <+212>: add r3, r3, lr 0xc07c2744 <+216>: add r0, r0, r5 55 out[i] = be64_to_cpu(src[ndigits - 1 - i]); 0xc07c2748 <+220>: ldm r3, {r1, r12} //<== ldm thus alignment exception 0xc07c274c <+224>: rev r12, r12 0xc07c2750 <+228>: str r12, [r2, #8]! 0xc07c2754 <+232>: rev r1, r1 0xc07c2758 <+236>: cmp r0, r2 0xc07c275c <+240>: sub r3, r3, #8 0xc07c2760 <+244>: str r1, [r2, #4]