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 33static inline int 34crypto_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 41static inline uint8_t 42crypto_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 49static inline int 50crypto_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 57static inline uint8_t 58crypto_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 65static inline int 66crypto_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 73static inline uint8_t 74crypto_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 81static inline int 82crypto_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 89static inline uint8_t 90crypto_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 102static inline uint32_t 103crypto_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 119static inline void 120crypto_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 133static inline uint64_t 134crypto_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 150static inline void 151crypto_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 164static inline uint32_t 165crypto_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 181static inline void 182crypto_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 190static inline uint32_t 191crypto_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 198static inline uint32_t 199crypto_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 206static inline uint64_t 207crypto_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 214static inline uint64_t 215crypto_ror_u64(uint64_t v, size_t shift) 216{ 217 return (v << (64 - shift)) | (v >> shift); 218} 219#endif 220 221#endif 222