1 #ifndef CRYPTONITE_ALIGN_H
2 #define CRYPTONITE_ALIGN_H
3
4 #include "cryptonite_bitfn.h"
5
6 #if (defined(__i386__))
7 # define UNALIGNED_ACCESS_OK
8 #elif defined(__x86_64__)
9 # define UNALIGNED_ACCESS_OK
10 #else
11 # define UNALIGNED_ACCESS_FAULT
12 #endif
13
14 /* n need to be power of 2.
15 * IS_ALIGNED(p,8) */
16 #define IS_ALIGNED(p,alignment) (((uintptr_t) (p)) & ((alignment)-1))
17
18 #ifdef WITH_ASSERT_ALIGNMENT
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <inttypes.h>
22 # define ASSERT_ALIGNMENT(up, alignment) \
23 do { if (IS_ALIGNED(up, alignment)) \
24 { printf("ALIGNMENT-ASSERT-FAILURE: %s:%d: ptr=%p alignment=%d\n", __FILE__, __LINE__, (void *) up, (alignment)); \
25 exit(99); \
26 }; } while (0)
27 #else
28 # define ASSERT_ALIGNMENT(p, n) do {} while (0)
29 #endif
30
31 #ifdef UNALIGNED_ACCESS_OK
32 #define need_alignment(p,n) (0)
33 #else
34 #define need_alignment(p,n) IS_ALIGNED(p,n)
35 #endif
36
load_le32_aligned(const uint8_t * p)37 static inline uint32_t load_le32_aligned(const uint8_t *p)
38 {
39 return le32_to_cpu(*((uint32_t *) p));
40 }
41
store_le32_aligned(uint8_t * dst,const uint32_t v)42 static inline void store_le32_aligned(uint8_t *dst, const uint32_t v)
43 {
44 *((uint32_t *) dst) = cpu_to_le32(v);
45 }
46
xor_le32_aligned(uint8_t * dst,const uint32_t v)47 static inline void xor_le32_aligned(uint8_t *dst, const uint32_t v)
48 {
49 *((uint32_t *) dst) ^= cpu_to_le32(v);
50 }
51
store_be32_aligned(uint8_t * dst,const uint32_t v)52 static inline void store_be32_aligned(uint8_t *dst, const uint32_t v)
53 {
54 *((uint32_t *) dst) = cpu_to_be32(v);
55 }
56
xor_be32_aligned(uint8_t * dst,const uint32_t v)57 static inline void xor_be32_aligned(uint8_t *dst, const uint32_t v)
58 {
59 *((uint32_t *) dst) ^= cpu_to_be32(v);
60 }
61
store_le64_aligned(uint8_t * dst,const uint64_t v)62 static inline void store_le64_aligned(uint8_t *dst, const uint64_t v)
63 {
64 *((uint64_t *) dst) = cpu_to_le64(v);
65 }
66
store_be64_aligned(uint8_t * dst,const uint64_t v)67 static inline void store_be64_aligned(uint8_t *dst, const uint64_t v)
68 {
69 *((uint64_t *) dst) = cpu_to_be64(v);
70 }
71
xor_be64_aligned(uint8_t * dst,const uint64_t v)72 static inline void xor_be64_aligned(uint8_t *dst, const uint64_t v)
73 {
74 *((uint64_t *) dst) ^= cpu_to_be64(v);
75 }
76
77 #ifdef UNALIGNED_ACCESS_OK
78 #define load_le32(a) load_le32_aligned(a)
79 #else
load_le32(const uint8_t * p)80 static inline uint32_t load_le32(const uint8_t *p)
81 {
82 return ((uint32_t)p[0]) | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
83 }
84 #endif
85
86 #ifdef UNALIGNED_ACCESS_OK
87 #define store_le32(a, b) store_le32_aligned(a, b)
88 #define xor_le32(a, b) xor_le32_aligned(a, b)
89 #else
store_le32(uint8_t * dst,const uint32_t v)90 static inline void store_le32(uint8_t *dst, const uint32_t v)
91 {
92 dst[0] = v; dst[1] = v >> 8; dst[2] = v >> 16; dst[3] = v >> 24;
93 }
xor_le32(uint8_t * dst,const uint32_t v)94 static inline void xor_le32(uint8_t *dst, const uint32_t v)
95 {
96 dst[0] ^= v; dst[1] ^= v >> 8; dst[2] ^= v >> 16; dst[3] ^= v >> 24;
97 }
98 #endif
99
100 #ifdef UNALIGNED_ACCESS_OK
101 #define store_be32(a, b) store_be32_aligned(a, b)
102 #define xor_be32(a, b) xor_be32_aligned(a, b)
103 #else
store_be32(uint8_t * dst,const uint32_t v)104 static inline void store_be32(uint8_t *dst, const uint32_t v)
105 {
106 dst[3] = v; dst[2] = v >> 8; dst[1] = v >> 16; dst[0] = v >> 24;
107 }
xor_be32(uint8_t * dst,const uint32_t v)108 static inline void xor_be32(uint8_t *dst, const uint32_t v)
109 {
110 dst[3] ^= v; dst[2] ^= v >> 8; dst[1] ^= v >> 16; dst[0] ^= v >> 24;
111 }
112 #endif
113
114 #ifdef UNALIGNED_ACCESS_OK
115 #define store_le64(a, b) store_le64_aligned(a, b)
116 #else
store_le64(uint8_t * dst,const uint64_t v)117 static inline void store_le64(uint8_t *dst, const uint64_t v)
118 {
119 dst[0] = v ; dst[1] = v >> 8 ; dst[2] = v >> 16; dst[3] = v >> 24;
120 dst[4] = v >> 32; dst[5] = v >> 40; dst[6] = v >> 48; dst[7] = v >> 56;
121 }
122 #endif
123
124 #ifdef UNALIGNED_ACCESS_OK
125 #define store_be64(a, b) store_be64_aligned(a, b)
126 #define xor_be64(a, b) xor_be64_aligned(a, b)
127 #else
store_be64(uint8_t * dst,const uint64_t v)128 static inline void store_be64(uint8_t *dst, const uint64_t v)
129 {
130 dst[7] = v ; dst[6] = v >> 8 ; dst[5] = v >> 16; dst[4] = v >> 24;
131 dst[3] = v >> 32; dst[2] = v >> 40; dst[1] = v >> 48; dst[0] = v >> 56;
132 }
xor_be64(uint8_t * dst,const uint64_t v)133 static inline void xor_be64(uint8_t *dst, const uint64_t v)
134 {
135 dst[7] ^= v ; dst[6] ^= v >> 8 ; dst[5] ^= v >> 16; dst[4] ^= v >> 24;
136 dst[3] ^= v >> 32; dst[2] ^= v >> 40; dst[1] ^= v >> 48; dst[0] ^= v >> 56;
137 }
138 #endif
139
140 #endif
141