xref: /openbsd/lib/libcrypto/crypto_internal.h (revision f66cfe6c)
1 /*	$OpenBSD: crypto_internal.h,v 1.10 2024/04/17 14:43:37 jsing Exp $ */
2 /*
3  * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <endian.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 #include <string.h>
22 
23 #ifndef HEADER_CRYPTO_INTERNAL_H
24 #define HEADER_CRYPTO_INTERNAL_H
25 
26 #define CTASSERT(x) \
27     extern char _ctassert[(x) ? 1 : -1] __attribute__((__unused__))
28 
29 /*
30  * Constant time operations for uint8_t.
31  */
32 #ifndef HAVE_CRYPTO_CT_NE_ZERO_U8
33 static inline int
crypto_ct_ne_zero_u8(uint8_t v)34 crypto_ct_ne_zero_u8(uint8_t v)
35 {
36 	return (uint8_t)(v | ~(v - 1)) >> ((sizeof(v) * 8) - 1);
37 }
38 #endif
39 
40 #ifndef HAVE_CRYPTO_CT_NE_ZERO_MASK_U8
41 static inline uint8_t
crypto_ct_ne_zero_mask_u8(uint8_t v)42 crypto_ct_ne_zero_mask_u8(uint8_t v)
43 {
44 	return 0 - crypto_ct_ne_zero_u8(v);
45 }
46 #endif
47 
48 #ifndef HAVE_CRYPTO_CT_EQ_ZERO_U8
49 static inline int
crypto_ct_eq_zero_u8(uint8_t v)50 crypto_ct_eq_zero_u8(uint8_t v)
51 {
52 	return 1 - crypto_ct_ne_zero_u8(v);
53 }
54 #endif
55 
56 #ifndef HAVE_CRYPTO_CT_EQ_ZERO_MASK_U8
57 static inline uint8_t
crypto_ct_eq_zero_mask_u8(uint8_t v)58 crypto_ct_eq_zero_mask_u8(uint8_t v)
59 {
60 	return 0 - crypto_ct_eq_zero_u8(v);
61 }
62 #endif
63 
64 #ifndef HAVE_CRYPTO_CT_NE_U8
65 static inline int
crypto_ct_ne_u8(uint8_t a,uint8_t b)66 crypto_ct_ne_u8(uint8_t a, uint8_t b)
67 {
68 	return crypto_ct_ne_zero_u8(a - b);
69 }
70 #endif
71 
72 #ifndef HAVE_CRYPTO_CT_NE_MASK_U8
73 static inline uint8_t
crypto_ct_ne_mask_u8(uint8_t a,uint8_t b)74 crypto_ct_ne_mask_u8(uint8_t a, uint8_t b)
75 {
76 	return 0 - crypto_ct_ne_u8(a, b);
77 }
78 #endif
79 
80 #ifndef HAVE_CRYPTO_CT_EQ_U8
81 static inline int
crypto_ct_eq_u8(uint8_t a,uint8_t b)82 crypto_ct_eq_u8(uint8_t a, uint8_t b)
83 {
84 	return crypto_ct_eq_zero_u8(a - b);
85 }
86 #endif
87 
88 #ifndef HAVE_CRYPTO_CT_EQ_MASK_U8
89 static inline uint8_t
crypto_ct_eq_mask_u8(uint8_t a,uint8_t b)90 crypto_ct_eq_mask_u8(uint8_t a, uint8_t b)
91 {
92 	return 0 - crypto_ct_eq_u8(a, b);
93 }
94 #endif
95 
96 /*
97  * crypto_load_be32toh() loads a 32 bit unsigned big endian value as a 32 bit
98  * unsigned host endian value, from the specified address in memory. The memory
99  * address may have any alignment.
100  */
101 #ifndef HAVE_CRYPTO_LOAD_BE32TOH
102 static inline uint32_t
crypto_load_be32toh(const uint8_t * src)103 crypto_load_be32toh(const uint8_t *src)
104 {
105 	uint32_t v;
106 
107 	memcpy(&v, src, sizeof(v));
108 
109 	return be32toh(v);
110 }
111 #endif
112 
113 /*
114  * crypto_store_htobe32() stores a 32 bit unsigned host endian value as a 32 bit
115  * unsigned big endian value, at the specified address in memory. The memory
116  * address may have any alignment.
117  */
118 #ifndef HAVE_CRYPTO_STORE_HTOBE32
119 static inline void
crypto_store_htobe32(uint8_t * dst,uint32_t v)120 crypto_store_htobe32(uint8_t *dst, uint32_t v)
121 {
122 	v = htobe32(v);
123 	memcpy(dst, &v, sizeof(v));
124 }
125 #endif
126 
127 /*
128  * crypto_load_be64toh() loads a 64 bit unsigned big endian value as a 64 bit
129  * unsigned host endian value, from the specified address in memory. The memory
130  * address may have any alignment.
131  */
132 #ifndef HAVE_CRYPTO_LOAD_BE64TOH
133 static inline uint64_t
crypto_load_be64toh(const uint8_t * src)134 crypto_load_be64toh(const uint8_t *src)
135 {
136 	uint64_t v;
137 
138 	memcpy(&v, src, sizeof(v));
139 
140 	return be64toh(v);
141 }
142 #endif
143 
144 /*
145  * crypto_store_htobe64() stores a 64 bit unsigned host endian value as a 64 bit
146  * unsigned big endian value, at the specified address in memory. The memory
147  * address may have any alignment.
148  */
149 #ifndef HAVE_CRYPTO_STORE_HTOBE64
150 static inline void
crypto_store_htobe64(uint8_t * dst,uint64_t v)151 crypto_store_htobe64(uint8_t *dst, uint64_t v)
152 {
153 	v = htobe64(v);
154 	memcpy(dst, &v, sizeof(v));
155 }
156 #endif
157 
158 /*
159  * crypto_load_le32toh() loads a 32 bit unsigned little endian value as a 32 bit
160  * unsigned host endian value, from the specified address in memory. The memory
161  * address may have any alignment.
162  */
163 #ifndef HAVE_CRYPTO_LOAD_LE32TOH
164 static inline uint32_t
crypto_load_le32toh(const uint8_t * src)165 crypto_load_le32toh(const uint8_t *src)
166 {
167 	uint32_t v;
168 
169 	memcpy(&v, src, sizeof(v));
170 
171 	return le32toh(v);
172 }
173 #endif
174 
175 /*
176  * crypto_store_htole32() stores a 32 bit unsigned host endian value as a 32 bit
177  * unsigned little endian value, at the specified address in memory. The memory
178  * address may have any alignment.
179  */
180 #ifndef HAVE_CRYPTO_STORE_HTOLE32
181 static inline void
crypto_store_htole32(uint8_t * dst,uint32_t v)182 crypto_store_htole32(uint8_t *dst, uint32_t v)
183 {
184 	v = htole32(v);
185 	memcpy(dst, &v, sizeof(v));
186 }
187 #endif
188 
189 #ifndef HAVE_CRYPTO_ROL_U32
190 static inline uint32_t
crypto_rol_u32(uint32_t v,size_t shift)191 crypto_rol_u32(uint32_t v, size_t shift)
192 {
193 	return (v << shift) | (v >> (32 - shift));
194 }
195 #endif
196 
197 #ifndef HAVE_CRYPTO_ROR_U32
198 static inline uint32_t
crypto_ror_u32(uint32_t v,size_t shift)199 crypto_ror_u32(uint32_t v, size_t shift)
200 {
201 	return (v << (32 - shift)) | (v >> shift);
202 }
203 #endif
204 
205 #ifndef HAVE_CRYPTO_ROL_U64
206 static inline uint64_t
crypto_rol_u64(uint64_t v,size_t shift)207 crypto_rol_u64(uint64_t v, size_t shift)
208 {
209 	return (v << shift) | (v >> (64 - shift));
210 }
211 #endif
212 
213 #ifndef HAVE_CRYPTO_ROR_U64
214 static inline uint64_t
crypto_ror_u64(uint64_t v,size_t shift)215 crypto_ror_u64(uint64_t v, size_t shift)
216 {
217 	return (v << (64 - shift)) | (v >> shift);
218 }
219 #endif
220 
221 #endif
222