Skip to content

Load64Unaligned: unaligned load faults on RISC-V cores without hardware unaligned-access support #10043

@gmazurki

Description

@gmazurki

Version

5.9.0

Description

When WC_SHA3_FAULT_HARDEN and WC_32BIT_CPU are both defined, Load64Unaligned in wolfcrypt/src/sha3.c casts its byte-pointer argument directly to word32* and dereferences it:

// sha3.c ~line 593
#elif defined(WC_32BIT_CPU)
    return (((word64)((word32*)a)[1]) << 32) |
                     ((word32*)a)[0];

Despite the function being named Load64Unaligned, this generates lw instructions (4-byte natural-alignment requirement) from a pointer that is only guaranteed to be byte-aligned. On RISC-V cores that do not implement hardware unaligned-access support (e.g. SiFive Secure E21, RV32IMAC), any call where data is not 4-byte aligned raises a load address misaligned CPU exception.

Proposed fix:

 #ifdef WC_64BIT_CPU
     return *(word64*)a;
 #elif defined(WC_32BIT_CPU)
-    return (((word64)((word32*)a)[1]) << 32) |
-                     ((word32*)a)[0];
+    /* Use XMEMCPY to avoid generating 'lw' instructions from a potentially
+     * unaligned pointer, which faults on RISC-V cores without hardware
+     * unaligned-access support (e.g. SiFive E21). */
+    word32 lo, hi;
+    XMEMCPY(&lo, a,     sizeof(lo));
+    XMEMCPY(&hi, a + 4, sizeof(hi));
+    return ((word64)hi << 32) | (word64)lo;
 #else
     return (((word64)((word16*)a)[3]) << 48) |
            (((word64)((word16*)a)[2]) << 32) |

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions