1 /*
2 * Copyright 2019-2024 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 #include <openssl/crypto.h>
11 #include "crypto/rand.h"
12 #include "crypto/dso_conf.h"
13 #include "internal/thread_once.h"
14 #include "internal/cryptlib.h"
15 #include "internal/e_os.h"
16 #include "buildinf.h"
17
18 #ifndef OPENSSL_NO_JITTER
19 # include <stdio.h>
20 # include <jitterentropy.h>
21 #endif
22
23 #if defined(__arm__) || defined(__arm) || defined(__aarch64__)
24 # include "arm_arch.h"
25 # define CPU_INFO_STR_LEN 128
26 #elif defined(__s390__) || defined(__s390x__)
27 # include "s390x_arch.h"
28 # define CPU_INFO_STR_LEN 2048
29 #elif defined(__riscv)
30 # include "crypto/riscv_arch.h"
31 # define CPU_INFO_STR_LEN 2048
32 #else
33 # define CPU_INFO_STR_LEN 128
34 #endif
35
36 /* extern declaration to avoid warning */
37 extern char ossl_cpu_info_str[];
38
39 static char *seed_sources = NULL;
40
41 char ossl_cpu_info_str[CPU_INFO_STR_LEN] = "";
42 #define CPUINFO_PREFIX "CPUINFO: "
43
44 static CRYPTO_ONCE init_info = CRYPTO_ONCE_STATIC_INIT;
45
DEFINE_RUN_ONCE_STATIC(init_info_strings)46 DEFINE_RUN_ONCE_STATIC(init_info_strings)
47 {
48 #if defined(OPENSSL_CPUID_OBJ)
49 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
50 defined(__x86_64) || defined(__x86_64__) || \
51 defined(_M_AMD64) || defined(_M_X64)
52 const char *env;
53
54 BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
55 CPUINFO_PREFIX "OPENSSL_ia32cap=0x%llx:0x%llx",
56 (unsigned long long)OPENSSL_ia32cap_P[0] |
57 (unsigned long long)OPENSSL_ia32cap_P[1] << 32,
58 (unsigned long long)OPENSSL_ia32cap_P[2] |
59 (unsigned long long)OPENSSL_ia32cap_P[3] << 32);
60 if ((env = getenv("OPENSSL_ia32cap")) != NULL)
61 BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
62 sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
63 " env:%s", env);
64 # elif defined(__arm__) || defined(__arm) || defined(__aarch64__)
65 const char *env;
66
67 BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
68 CPUINFO_PREFIX "OPENSSL_armcap=0x%x", OPENSSL_armcap_P);
69 if ((env = getenv("OPENSSL_armcap")) != NULL)
70 BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
71 sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
72 " env:%s", env);
73 # elif defined(__s390__) || defined(__s390x__)
74 const char *env;
75
76 BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
77 CPUINFO_PREFIX "OPENSSL_s390xcap="
78 "stfle:0x%llx:0x%llx:0x%llx:0x%llx:"
79 "kimd:0x%llx:0x%llx:"
80 "klmd:0x%llx:0x%llx:"
81 "km:0x%llx:0x%llx:"
82 "kmc:0x%llx:0x%llx:"
83 "kmac:0x%llx:0x%llx:"
84 "kmctr:0x%llx:0x%llx:"
85 "kmo:0x%llx:0x%llx:"
86 "kmf:0x%llx:0x%llx:"
87 "prno:0x%llx:0x%llx:"
88 "kma:0x%llx:0x%llx:"
89 "pcc:0x%llx:0x%llx:"
90 "kdsa:0x%llx:0x%llx",
91 OPENSSL_s390xcap_P.stfle[0], OPENSSL_s390xcap_P.stfle[1],
92 OPENSSL_s390xcap_P.stfle[2], OPENSSL_s390xcap_P.stfle[3],
93 OPENSSL_s390xcap_P.kimd[0], OPENSSL_s390xcap_P.kimd[1],
94 OPENSSL_s390xcap_P.klmd[0], OPENSSL_s390xcap_P.klmd[1],
95 OPENSSL_s390xcap_P.km[0], OPENSSL_s390xcap_P.km[1],
96 OPENSSL_s390xcap_P.kmc[0], OPENSSL_s390xcap_P.kmc[1],
97 OPENSSL_s390xcap_P.kmac[0], OPENSSL_s390xcap_P.kmac[1],
98 OPENSSL_s390xcap_P.kmctr[0], OPENSSL_s390xcap_P.kmctr[1],
99 OPENSSL_s390xcap_P.kmo[0], OPENSSL_s390xcap_P.kmo[1],
100 OPENSSL_s390xcap_P.kmf[0], OPENSSL_s390xcap_P.kmf[1],
101 OPENSSL_s390xcap_P.prno[0], OPENSSL_s390xcap_P.prno[1],
102 OPENSSL_s390xcap_P.kma[0], OPENSSL_s390xcap_P.kma[1],
103 OPENSSL_s390xcap_P.pcc[0], OPENSSL_s390xcap_P.pcc[1],
104 OPENSSL_s390xcap_P.kdsa[0], OPENSSL_s390xcap_P.kdsa[1]);
105 if ((env = getenv("OPENSSL_s390xcap")) != NULL)
106 BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
107 sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
108 " env:%s", env);
109 # elif defined(__riscv)
110 const char *env;
111 char sep = '=';
112
113 BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
114 CPUINFO_PREFIX "OPENSSL_riscvcap");
115 for (size_t i = 0; i < kRISCVNumCaps; ++i) {
116 if (OPENSSL_riscvcap_P[RISCV_capabilities[i].index]
117 & (1 << RISCV_capabilities[i].bit_offset)) {
118 /* Match, display the name */
119 BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
120 sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
121 "%c%s", sep, RISCV_capabilities[i].name);
122 /* Only the first sep is '=' */
123 sep = '_';
124 }
125 }
126 /* If no capability is found, add back the = */
127 if (sep == '=') {
128 BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
129 sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
130 "%c", sep);
131 }
132 if ((env = getenv("OPENSSL_riscvcap")) != NULL)
133 BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
134 sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
135 " env:%s", env);
136 # endif
137 #endif
138
139 {
140 static char seeds[512] = "";
141
142 #define add_seeds_string(str) \
143 do { \
144 if (seeds[0] != '\0') \
145 OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \
146 OPENSSL_strlcat(seeds, str, sizeof(seeds)); \
147 } while (0)
148 #define add_seeds_stringlist(label, strlist) \
149 do { \
150 add_seeds_string(label "("); \
151 { \
152 const char *dev[] = { strlist, NULL }; \
153 const char **p; \
154 int first = 1; \
155 \
156 for (p = dev; *p != NULL; p++) { \
157 if (!first) \
158 OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \
159 first = 0; \
160 OPENSSL_strlcat(seeds, *p, sizeof(seeds)); \
161 } \
162 } \
163 OPENSSL_strlcat(seeds, ")", sizeof(seeds)); \
164 } while (0)
165
166 #ifdef OPENSSL_RAND_SEED_NONE
167 add_seeds_string("none");
168 #endif
169 #ifdef OPENSSL_RAND_SEED_RDTSC
170 add_seeds_string("rdtsc");
171 #endif
172 #ifdef OPENSSL_RAND_SEED_RDCPU
173 # ifdef __aarch64__
174 add_seeds_string("rndr ( rndrrs rndr )");
175 # else
176 add_seeds_string("rdrand ( rdseed rdrand )");
177 # endif
178 #endif
179 #ifdef OPENSSL_RAND_SEED_GETRANDOM
180 add_seeds_string("getrandom-syscall");
181 #endif
182 #ifdef OPENSSL_RAND_SEED_DEVRANDOM
183 add_seeds_stringlist("random-device", DEVRANDOM);
184 #endif
185 #ifdef OPENSSL_RAND_SEED_EGD
186 add_seeds_stringlist("EGD", DEVRANDOM_EGD);
187 #endif
188 #ifdef OPENSSL_RAND_SEED_OS
189 add_seeds_string("os-specific");
190 #endif
191 #ifndef OPENSSL_NO_JITTER
192 {
193 char buf[32];
194
195 BIO_snprintf(buf, sizeof(buf), "JITTER (%d)", jent_version());
196 add_seeds_string(buf);
197 }
198 #endif
199 seed_sources = seeds;
200 }
201 return 1;
202 }
203
OPENSSL_info(int t)204 const char *OPENSSL_info(int t)
205 {
206 /*
207 * We don't care about the result. Worst case scenario, the strings
208 * won't be initialised, i.e. remain NULL, which means that the info
209 * isn't available anyway...
210 */
211 (void)RUN_ONCE(&init_info, init_info_strings);
212
213 switch (t) {
214 case OPENSSL_INFO_CONFIG_DIR:
215 return ossl_get_openssldir();
216 case OPENSSL_INFO_ENGINES_DIR:
217 return ossl_get_enginesdir();
218 case OPENSSL_INFO_MODULES_DIR:
219 return ossl_get_modulesdir();
220 case OPENSSL_INFO_DSO_EXTENSION:
221 return DSO_EXTENSION;
222 case OPENSSL_INFO_DIR_FILENAME_SEPARATOR:
223 #if defined(_WIN32)
224 return "\\";
225 #elif defined(__VMS)
226 return "";
227 #else /* Assume POSIX */
228 return "/";
229 #endif
230 case OPENSSL_INFO_LIST_SEPARATOR:
231 {
232 static const char list_sep[] = { LIST_SEPARATOR_CHAR, '\0' };
233 return list_sep;
234 }
235 case OPENSSL_INFO_SEED_SOURCE:
236 return seed_sources;
237 case OPENSSL_INFO_CPU_SETTINGS:
238 /*
239 * If successfully initialized, ossl_cpu_info_str will start
240 * with CPUINFO_PREFIX, if failed it will be an empty string.
241 * Strip away the CPUINFO_PREFIX which we don't need here.
242 */
243 if (ossl_cpu_info_str[0] != '\0')
244 return ossl_cpu_info_str + strlen(CPUINFO_PREFIX);
245 break;
246 case OPENSSL_INFO_WINDOWS_CONTEXT:
247 return ossl_get_wininstallcontext();
248 default:
249 break;
250 }
251 /* Not an error */
252 return NULL;
253 }
254