Coverage Report

Created: 2025-11-14 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/info.c
Line
Count
Source
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(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC)
27
# include "crypto/ppc_arch.h"
28
# define CPU_INFO_STR_LEN 128
29
#elif defined(__sparcv9) || defined(__sparcv9__)
30
# include "crypto/sparc_arch.h"
31
# define CPU_INFO_STR_LEN 128
32
#elif defined(__s390__) || defined(__s390x__)
33
# include "s390x_arch.h"
34
# define CPU_INFO_STR_LEN 2048
35
#elif defined(__riscv)
36
# include "crypto/riscv_arch.h"
37
# define CPU_INFO_STR_LEN 2048
38
#else
39
# define CPU_INFO_STR_LEN 256
40
#endif
41
42
/* extern declaration to avoid warning */
43
extern char ossl_cpu_info_str[];
44
45
static char *seed_sources = NULL;
46
47
char ossl_cpu_info_str[CPU_INFO_STR_LEN] = "";
48
0
#define CPUINFO_PREFIX "CPUINFO: "
49
50
static CRYPTO_ONCE init_info = CRYPTO_ONCE_STATIC_INIT;
51
52
DEFINE_RUN_ONCE_STATIC(init_info_strings)
53
0
{
54
0
#if defined(OPENSSL_CPUID_OBJ)
55
0
# if defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
56
0
     defined(__x86_64) || defined(__x86_64__) || \
57
0
     defined(_M_AMD64) || defined(_M_X64)
58
0
    const char *env;
59
60
0
    BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
61
0
                 CPUINFO_PREFIX "OPENSSL_ia32cap=0x%.16llx:0x%.16llx:0x%.16llx:0x%.16llx:0x%.16llx",
62
0
                 (unsigned long long)OPENSSL_ia32cap_P[0] |
63
0
                 (unsigned long long)OPENSSL_ia32cap_P[1] << 32,
64
0
                 (unsigned long long)OPENSSL_ia32cap_P[2] |
65
0
                 (unsigned long long)OPENSSL_ia32cap_P[3] << 32,
66
0
                 (unsigned long long)OPENSSL_ia32cap_P[4] |
67
0
                 (unsigned long long)OPENSSL_ia32cap_P[5] << 32,
68
0
                 (unsigned long long)OPENSSL_ia32cap_P[6] |
69
0
                 (unsigned long long)OPENSSL_ia32cap_P[7] << 32,
70
0
                 (unsigned long long)OPENSSL_ia32cap_P[8] |
71
0
                 (unsigned long long)OPENSSL_ia32cap_P[9] << 32);
72
73
0
    if ((env = getenv("OPENSSL_ia32cap")) != NULL)
74
0
        BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
75
0
                     sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
76
0
                     " env:%s", env);
77
# elif defined(__arm__) || defined(__arm) || defined(__aarch64__)
78
    const char *env;
79
80
    BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
81
                 CPUINFO_PREFIX "OPENSSL_armcap=0x%x", OPENSSL_armcap_P);
82
    if ((env = getenv("OPENSSL_armcap")) != NULL)
83
        BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
84
                     sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
85
                     " env:%s", env);
86
# elif defined(__powerpc__) || defined(__POWERPC__) || defined(_ARCH_PPC)
87
    const char *env;
88
89
    BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
90
                 CPUINFO_PREFIX "OPENSSL_ppccap=0x%x", OPENSSL_ppccap_P);
91
    if ((env = getenv("OPENSSL_ppccap")) != NULL)
92
        BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
93
                     sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
94
                     " env:%s", env);
95
# elif defined(__sparcv9) || defined(__sparcv9__)
96
    const char *env;
97
98
    BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
99
                 CPUINFO_PREFIX "OPENSSL_sparcv9cap=0x%x:0x%x",
100
                 OPENSSL_sparcv9cap_P[0], OPENSSL_sparcv9cap_P[1]);
101
    if ((env = getenv("OPENSSL_sparcv9cap")) != NULL)
102
        BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
103
                     sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
104
                     " env:%s", env);
105
# elif defined(__s390__) || defined(__s390x__)
106
    const char *env;
107
108
    BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
109
                 CPUINFO_PREFIX "OPENSSL_s390xcap="
110
                 "stfle:0x%llx:0x%llx:0x%llx:0x%llx:"
111
                 "kimd:0x%llx:0x%llx:"
112
                 "klmd:0x%llx:0x%llx:"
113
                 "km:0x%llx:0x%llx:"
114
                 "kmc:0x%llx:0x%llx:"
115
                 "kmac:0x%llx:0x%llx:"
116
                 "kmctr:0x%llx:0x%llx:"
117
                 "kmo:0x%llx:0x%llx:"
118
                 "kmf:0x%llx:0x%llx:"
119
                 "prno:0x%llx:0x%llx:"
120
                 "kma:0x%llx:0x%llx:"
121
                 "pcc:0x%llx:0x%llx:"
122
                 "kdsa:0x%llx:0x%llx",
123
                 OPENSSL_s390xcap_P.stfle[0], OPENSSL_s390xcap_P.stfle[1],
124
                 OPENSSL_s390xcap_P.stfle[2], OPENSSL_s390xcap_P.stfle[3],
125
                 OPENSSL_s390xcap_P.kimd[0], OPENSSL_s390xcap_P.kimd[1],
126
                 OPENSSL_s390xcap_P.klmd[0], OPENSSL_s390xcap_P.klmd[1],
127
                 OPENSSL_s390xcap_P.km[0], OPENSSL_s390xcap_P.km[1],
128
                 OPENSSL_s390xcap_P.kmc[0], OPENSSL_s390xcap_P.kmc[1],
129
                 OPENSSL_s390xcap_P.kmac[0], OPENSSL_s390xcap_P.kmac[1],
130
                 OPENSSL_s390xcap_P.kmctr[0], OPENSSL_s390xcap_P.kmctr[1],
131
                 OPENSSL_s390xcap_P.kmo[0], OPENSSL_s390xcap_P.kmo[1],
132
                 OPENSSL_s390xcap_P.kmf[0], OPENSSL_s390xcap_P.kmf[1],
133
                 OPENSSL_s390xcap_P.prno[0], OPENSSL_s390xcap_P.prno[1],
134
                 OPENSSL_s390xcap_P.kma[0], OPENSSL_s390xcap_P.kma[1],
135
                 OPENSSL_s390xcap_P.pcc[0], OPENSSL_s390xcap_P.pcc[1],
136
                 OPENSSL_s390xcap_P.kdsa[0], OPENSSL_s390xcap_P.kdsa[1]);
137
    if ((env = getenv("OPENSSL_s390xcap")) != NULL)
138
        BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
139
                     sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
140
                     " env:%s", env);
141
# elif defined(__riscv)
142
    const char *env;
143
    size_t i;
144
145
    BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str),
146
                 CPUINFO_PREFIX "OPENSSL_riscvcap=RV"
147
#  if __riscv_xlen == 32
148
                 "32"
149
#  elif __riscv_xlen == 64
150
                 "64"
151
#  elif __riscv_xlen == 128
152
                 "128"
153
#  endif
154
#  if defined(__riscv_i) && defined(__riscv_m) && defined(__riscv_a) \
155
      && defined(__riscv_f) && defined(__riscv_d) \
156
      && defined(__riscv_zicsr) && defined(__riscv_zifencei)
157
                 "G" /* shorthand for IMAFD_Zicsr_Zifencei */
158
#  else
159
#   ifdef __riscv_i
160
                 "I"
161
#   endif
162
#   ifdef __riscv_m
163
                 "M"
164
#   endif
165
#   ifdef __riscv_a
166
                 "A"
167
#   endif
168
#   ifdef __riscv_f
169
                 "F"
170
#   endif
171
#   ifdef __riscv_d
172
                 "D"
173
#   endif
174
#  endif
175
#  ifdef __riscv_c
176
                 "C"
177
#  endif
178
                 );
179
    for (i = 0; i < kRISCVNumCaps; i++) {
180
        if (OPENSSL_riscvcap_P[RISCV_capabilities[i].index]
181
                & (1 << RISCV_capabilities[i].bit_offset))
182
            /* Match, display the name */
183
            BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
184
                         sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
185
                         "_%s", RISCV_capabilities[i].name);
186
    }
187
    if (RISCV_HAS_V())
188
        BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
189
                     sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
190
                     " vlen:%lu", riscv_vlen());
191
    if ((env = getenv("OPENSSL_riscvcap")) != NULL)
192
        BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str),
193
                     sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str),
194
                     " env:%s", env);
195
# endif
196
0
#endif
197
198
0
    {
199
0
        static char seeds[512] = "";
200
201
0
#define add_seeds_string(str)                                           \
202
0
        do {                                                            \
203
0
            if (seeds[0] != '\0')                                       \
204
0
                OPENSSL_strlcat(seeds, " ", sizeof(seeds));             \
205
0
            OPENSSL_strlcat(seeds, str, sizeof(seeds));                 \
206
0
        } while (0)
207
0
#define add_seeds_stringlist(label, strlist)                            \
208
0
        do {                                                            \
209
0
            add_seeds_string(label "(");                                \
210
0
            {                                                           \
211
0
                const char *dev[] =  { strlist, NULL };                 \
212
0
                const char **p;                                         \
213
0
                int first = 1;                                          \
214
0
                                                                        \
215
0
                for (p = dev; *p != NULL; p++) {                        \
216
0
                    if (!first)                                         \
217
0
                        OPENSSL_strlcat(seeds, " ", sizeof(seeds));     \
218
0
                    first = 0;                                          \
219
0
                    OPENSSL_strlcat(seeds, *p, sizeof(seeds));          \
220
0
                }                                                       \
221
0
            }                                                           \
222
0
            OPENSSL_strlcat(seeds, ")", sizeof(seeds));                 \
223
0
        } while (0)
224
225
#ifdef OPENSSL_RAND_SEED_NONE
226
        add_seeds_string("none");
227
#endif
228
#ifdef OPENSSL_RAND_SEED_RDTSC
229
        add_seeds_string("rdtsc");
230
#endif
231
#ifdef OPENSSL_RAND_SEED_RDCPU
232
# ifdef __aarch64__
233
        add_seeds_string("rndr ( rndrrs rndr )");
234
# else
235
        add_seeds_string("rdrand ( rdseed rdrand )");
236
# endif
237
#endif
238
#ifdef OPENSSL_RAND_SEED_GETRANDOM
239
        add_seeds_string("getrandom-syscall");
240
#endif
241
#ifdef OPENSSL_RAND_SEED_DEVRANDOM
242
        add_seeds_stringlist("random-device", DEVRANDOM);
243
#endif
244
#ifdef OPENSSL_RAND_SEED_EGD
245
        add_seeds_stringlist("EGD", DEVRANDOM_EGD);
246
#endif
247
0
#ifdef OPENSSL_RAND_SEED_OS
248
0
        add_seeds_string("os-specific");
249
0
#endif
250
#ifndef OPENSSL_NO_JITTER
251
        {
252
            char buf[32];
253
254
            BIO_snprintf(buf, sizeof(buf), "JITTER (%d)", jent_version());
255
            add_seeds_string(buf);
256
        }
257
#endif
258
0
        seed_sources = seeds;
259
0
    }
260
0
    return 1;
261
0
}
262
263
const char *OPENSSL_info(int t)
264
0
{
265
    /*
266
     * We don't care about the result.  Worst case scenario, the strings
267
     * won't be initialised, i.e. remain NULL, which means that the info
268
     * isn't available anyway...
269
     */
270
0
    (void)RUN_ONCE(&init_info, init_info_strings);
271
272
0
    switch (t) {
273
0
    case OPENSSL_INFO_CONFIG_DIR:
274
0
        return ossl_get_openssldir();
275
0
    case OPENSSL_INFO_ENGINES_DIR:
276
0
        return ossl_get_enginesdir();
277
0
    case OPENSSL_INFO_MODULES_DIR:
278
0
        return ossl_get_modulesdir();
279
0
    case OPENSSL_INFO_DSO_EXTENSION:
280
0
        return DSO_EXTENSION;
281
0
    case OPENSSL_INFO_DIR_FILENAME_SEPARATOR:
282
#if defined(_WIN32)
283
        return "\\";
284
#elif defined(__VMS)
285
        return "";
286
#else  /* Assume POSIX */
287
0
        return "/";
288
0
#endif
289
0
    case OPENSSL_INFO_LIST_SEPARATOR:
290
0
        {
291
0
            static const char list_sep[] = { LIST_SEPARATOR_CHAR, '\0' };
292
0
            return list_sep;
293
0
        }
294
0
    case OPENSSL_INFO_SEED_SOURCE:
295
0
        return seed_sources;
296
0
    case OPENSSL_INFO_CPU_SETTINGS:
297
        /*
298
         * If successfully initialized, ossl_cpu_info_str will start
299
         * with CPUINFO_PREFIX, if failed it will be an empty string.
300
         * Strip away the CPUINFO_PREFIX which we don't need here.
301
         */
302
0
        if (ossl_cpu_info_str[0] != '\0')
303
0
            return ossl_cpu_info_str + strlen(CPUINFO_PREFIX);
304
0
        break;
305
0
    case OPENSSL_INFO_WINDOWS_CONTEXT:
306
0
        return ossl_get_wininstallcontext();
307
0
    default:
308
0
        break;
309
0
    }
310
    /* Not an error */
311
0
    return NULL;
312
0
}