1 /*
2 * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #ifndef OSSL_INTERNAL_COMMON_H
11 #define OSSL_INTERNAL_COMMON_H
12 #pragma once
13
14 #include <stdlib.h>
15 #include <string.h>
16 #include "openssl/configuration.h"
17
18 #include "internal/e_os.h" /* ossl_inline in many files */
19 #include "internal/nelem.h"
20
21 #if defined(__GNUC__) || defined(__clang__)
22 #define ossl_likely(x) __builtin_expect(!!(x), 1)
23 #define ossl_unlikely(x) __builtin_expect(!!(x), 0)
24 #else
25 #define ossl_likely(x) (x)
26 #define ossl_unlikely(x) (x)
27 #endif
28
29 #if defined(__GNUC__) || defined(__clang__)
30 #define ALIGN32 __attribute((aligned(32)))
31 #define ALIGN64 __attribute((aligned(64)))
32 #elif defined(_MSC_VER)
33 #define ALIGN32 __declspec(align(32))
34 #define ALIGN64 __declspec(align(64))
35 #else
36 #define ALIGN32
37 #define ALIGN64
38 #endif
39
40 #ifdef NDEBUG
41 #define ossl_assert(x) ossl_likely((x) != 0)
42 #else
ossl_assert_int(int expr,const char * exprstr,const char * file,int line)43 __owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr,
44 const char *file, int line)
45 {
46 if (!expr)
47 OPENSSL_die(exprstr, file, line);
48
49 return expr;
50 }
51
52 #define ossl_assert(x) ossl_assert_int((x) != 0, "Assertion failed: " #x, \
53 __FILE__, __LINE__)
54
55 #endif
56
57 /* Check if |pre|, which must be a string literal, is a prefix of |str| */
58 #define HAS_PREFIX(str, pre) (strncmp(str, pre "", sizeof(pre) - 1) == 0)
59 /* As before, and if check succeeds, advance |str| past the prefix |pre| */
60 #define CHECK_AND_SKIP_PREFIX(str, pre) \
61 (HAS_PREFIX(str, pre) ? ((str) += sizeof(pre) - 1, 1) : 0)
62 /* Check if the string literal |p| is a case-insensitive prefix of |s| */
63 #define HAS_CASE_PREFIX(s, p) (OPENSSL_strncasecmp(s, p "", sizeof(p) - 1) == 0)
64 /* As before, and if check succeeds, advance |str| past the prefix |pre| */
65 #define CHECK_AND_SKIP_CASE_PREFIX(str, pre) \
66 (HAS_CASE_PREFIX(str, pre) ? ((str) += sizeof(pre) - 1, 1) : 0)
67 /* Check if the string literal |suffix| is a case-insensitive suffix of |str| */
68 #define HAS_CASE_SUFFIX(str, suffix) (strlen(str) < sizeof(suffix) - 1 ? 0 : OPENSSL_strcasecmp(str + strlen(str) - sizeof(suffix) + 1, suffix "") == 0)
69
70 /*
71 * Use this inside a union with the field that needs to be aligned to a
72 * reasonable boundary for the platform. The most pessimistic alignment
73 * of the listed types will be used by the compiler.
74 */
75 #define OSSL_UNION_ALIGN \
76 double align; \
77 ossl_uintmax_t align_int; \
78 void *align_ptr
79
80 #define OPENSSL_CONF "openssl.cnf"
81
82 #ifndef OPENSSL_SYS_VMS
83 #define X509_CERT_AREA OPENSSLDIR
84 #define X509_CERT_DIR OPENSSLDIR "/certs"
85 #define X509_CERT_FILE OPENSSLDIR "/cert.pem"
86 #define X509_PRIVATE_DIR OPENSSLDIR "/private"
87 #define CTLOG_FILE OPENSSLDIR "/ct_log_list.cnf"
88 #else
89 #define X509_CERT_AREA "OSSL$DATAROOT:[000000]"
90 #define X509_CERT_DIR "OSSL$DATAROOT:[CERTS]"
91 #define X509_CERT_FILE "OSSL$DATAROOT:[000000]cert.pem"
92 #define X509_PRIVATE_DIR "OSSL$DATAROOT:[PRIVATE]"
93 #define CTLOG_FILE "OSSL$DATAROOT:[000000]ct_log_list.cnf"
94 #endif
95
96 #define X509_CERT_DIR_EVP "SSL_CERT_DIR"
97 #define X509_CERT_FILE_EVP "SSL_CERT_FILE"
98 #define CTLOG_FILE_EVP "CTLOG_FILE"
99
100 /* size of string representations */
101 #define DECIMAL_SIZE(type) ((sizeof(type) * 8 + 2) / 3 + 1)
102 #define HEX_SIZE(type) (sizeof(type) * 2)
103
104 #define c2l(c, l) (l = ((unsigned long)(*((c)++))), \
105 l |= (((unsigned long)(*((c)++))) << 8), \
106 l |= (((unsigned long)(*((c)++))) << 16), \
107 l |= (((unsigned long)(*((c)++))) << 24))
108
109 /* NOTE - c is not incremented as per c2l */
110 #define c2ln(c, l1, l2, n) \
111 { \
112 c += n; \
113 l1 = l2 = 0; \
114 switch (n) { \
115 case 8: \
116 l2 = ((unsigned long)(*(--(c)))) << 24; \
117 case 7: \
118 l2 |= ((unsigned long)(*(--(c)))) << 16; \
119 case 6: \
120 l2 |= ((unsigned long)(*(--(c)))) << 8; \
121 case 5: \
122 l2 |= ((unsigned long)(*(--(c)))); \
123 case 4: \
124 l1 = ((unsigned long)(*(--(c)))) << 24; \
125 case 3: \
126 l1 |= ((unsigned long)(*(--(c)))) << 16; \
127 case 2: \
128 l1 |= ((unsigned long)(*(--(c)))) << 8; \
129 case 1: \
130 l1 |= ((unsigned long)(*(--(c)))); \
131 } \
132 }
133
134 #define l2c(l, c) (*((c)++) = (unsigned char)(((l)) & 0xff), \
135 *((c)++) = (unsigned char)(((l) >> 8) & 0xff), \
136 *((c)++) = (unsigned char)(((l) >> 16) & 0xff), \
137 *((c)++) = (unsigned char)(((l) >> 24) & 0xff))
138
139 #define n2l(c, l) (l = ((unsigned long)(*((c)++))) << 24, \
140 l |= ((unsigned long)(*((c)++))) << 16, \
141 l |= ((unsigned long)(*((c)++))) << 8, \
142 l |= ((unsigned long)(*((c)++))))
143
144 #define n2l8(c, l) (l = ((uint64_t)(*((c)++))) << 56, \
145 l |= ((uint64_t)(*((c)++))) << 48, \
146 l |= ((uint64_t)(*((c)++))) << 40, \
147 l |= ((uint64_t)(*((c)++))) << 32, \
148 l |= ((uint64_t)(*((c)++))) << 24, \
149 l |= ((uint64_t)(*((c)++))) << 16, \
150 l |= ((uint64_t)(*((c)++))) << 8, \
151 l |= ((uint64_t)(*((c)++))))
152
153 #define l2n(l, c) (*((c)++) = (unsigned char)(((l) >> 24) & 0xff), \
154 *((c)++) = (unsigned char)(((l) >> 16) & 0xff), \
155 *((c)++) = (unsigned char)(((l) >> 8) & 0xff), \
156 *((c)++) = (unsigned char)(((l)) & 0xff))
157
158 #define l2n8(l, c) (*((c)++) = (unsigned char)(((l) >> 56) & 0xff), \
159 *((c)++) = (unsigned char)(((l) >> 48) & 0xff), \
160 *((c)++) = (unsigned char)(((l) >> 40) & 0xff), \
161 *((c)++) = (unsigned char)(((l) >> 32) & 0xff), \
162 *((c)++) = (unsigned char)(((l) >> 24) & 0xff), \
163 *((c)++) = (unsigned char)(((l) >> 16) & 0xff), \
164 *((c)++) = (unsigned char)(((l) >> 8) & 0xff), \
165 *((c)++) = (unsigned char)(((l)) & 0xff))
166
167 /* NOTE - c is not incremented as per l2c */
168 #define l2cn(l1, l2, c, n) \
169 { \
170 c += n; \
171 switch (n) { \
172 case 8: \
173 *(--(c)) = (unsigned char)(((l2) >> 24) & 0xff); \
174 case 7: \
175 *(--(c)) = (unsigned char)(((l2) >> 16) & 0xff); \
176 case 6: \
177 *(--(c)) = (unsigned char)(((l2) >> 8) & 0xff); \
178 case 5: \
179 *(--(c)) = (unsigned char)(((l2)) & 0xff); \
180 case 4: \
181 *(--(c)) = (unsigned char)(((l1) >> 24) & 0xff); \
182 case 3: \
183 *(--(c)) = (unsigned char)(((l1) >> 16) & 0xff); \
184 case 2: \
185 *(--(c)) = (unsigned char)(((l1) >> 8) & 0xff); \
186 case 1: \
187 *(--(c)) = (unsigned char)(((l1)) & 0xff); \
188 } \
189 }
190
191 #define n2s(c, s) ((s = (((unsigned int)((c)[0])) << 8) | (((unsigned int)((c)[1])))), (c) += 2)
192 #define s2n(s, c) (((c)[0] = (unsigned char)(((s) >> 8) & 0xff), \
193 (c)[1] = (unsigned char)(((s)) & 0xff)), \
194 (c) += 2)
195
196 #define n2l3(c, l) ((l = (((unsigned long)((c)[0])) << 16) | (((unsigned long)((c)[1])) << 8) | (((unsigned long)((c)[2])))), (c) += 3)
197
198 #define l2n3(l, c) (((c)[0] = (unsigned char)(((l) >> 16) & 0xff), \
199 (c)[1] = (unsigned char)(((l) >> 8) & 0xff), \
200 (c)[2] = (unsigned char)(((l)) & 0xff)), \
201 (c) += 3)
202
ossl_ends_with_dirsep(const char * path)203 static ossl_inline int ossl_ends_with_dirsep(const char *path)
204 {
205 if (*path != '\0')
206 path += strlen(path) - 1;
207 #if defined __VMS
208 if (*path == ']' || *path == '>' || *path == ':')
209 return 1;
210 #elif defined _WIN32
211 if (*path == '\\')
212 return 1;
213 #endif
214 return *path == '/';
215 }
216
ossl_determine_dirsep(const char * path)217 static ossl_inline char ossl_determine_dirsep(const char *path)
218 {
219 if (ossl_ends_with_dirsep(path))
220 return '\0';
221
222 #if defined(_WIN32)
223 return '\\';
224 #elif defined(__VMS)
225 return ':';
226 #else
227 return '/';
228 #endif
229 }
230
ossl_is_absolute_path(const char * path)231 static ossl_inline int ossl_is_absolute_path(const char *path)
232 {
233 #if defined __VMS
234 if (strchr(path, ':') != NULL
235 || ((path[0] == '[' || path[0] == '<')
236 && path[1] != '.' && path[1] != '-'
237 && path[1] != ']' && path[1] != '>'))
238 return 1;
239 #elif defined _WIN32
240 if (path[0] == '\\'
241 || (path[0] != '\0' && path[1] == ':'))
242 return 1;
243 #endif
244 return path[0] == '/';
245 }
246
247 const char *ossl_get_openssldir(void);
248 const char *ossl_get_enginesdir(void);
249 const char *ossl_get_modulesdir(void);
250 const char *ossl_get_wininstallcontext(void);
251
252 #endif
253