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