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