| /* |
| * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. |
| * |
| * Licensed under the Apache License 2.0 (the "License"). You may not use |
| * this file except in compliance with the License. You can obtain a copy |
| * in the file LICENSE in the source distribution or at |
| * https://www.openssl.org/source/license.html |
| */ |
| |
| #include <openssl/crypto.h> |
| #include "crypto/rand.h" |
| #include "crypto/dso_conf.h" |
| #include "internal/thread_once.h" |
| #include "internal/cryptlib.h" |
| #include "internal/e_os.h" |
| #include "buildinf.h" |
| |
| #if defined(__arm__) || defined(__arm) || defined(__aarch64__) |
| # include "arm_arch.h" |
| # define CPU_INFO_STR_LEN 128 |
| #elif defined(__s390__) || defined(__s390x__) |
| # include "s390x_arch.h" |
| # define CPU_INFO_STR_LEN 2048 |
| #else |
| # define CPU_INFO_STR_LEN 128 |
| #endif |
| |
| /* extern declaration to avoid warning */ |
| extern char ossl_cpu_info_str[]; |
| |
| static char *seed_sources = NULL; |
| |
| char ossl_cpu_info_str[CPU_INFO_STR_LEN] = ""; |
| #define CPUINFO_PREFIX "CPUINFO: " |
| |
| static CRYPTO_ONCE init_info = CRYPTO_ONCE_STATIC_INIT; |
| |
| DEFINE_RUN_ONCE_STATIC(init_info_strings) |
| { |
| #if defined(OPENSSL_CPUID_OBJ) |
| # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ |
| defined(__x86_64) || defined(__x86_64__) || \ |
| defined(_M_AMD64) || defined(_M_X64) |
| const char *env; |
| |
| BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), |
| CPUINFO_PREFIX "OPENSSL_ia32cap=0x%llx:0x%llx", |
| (long long)OPENSSL_ia32cap_P[0] | |
| (long long)OPENSSL_ia32cap_P[1] << 32, |
| (long long)OPENSSL_ia32cap_P[2] | |
| (long long)OPENSSL_ia32cap_P[3] << 32); |
| if ((env = getenv("OPENSSL_ia32cap")) != NULL) |
| BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), |
| sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), |
| " env:%s", env); |
| # elif defined(__arm__) || defined(__arm) || defined(__aarch64__) |
| const char *env; |
| |
| BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), |
| CPUINFO_PREFIX "OPENSSL_armcap=0x%x", OPENSSL_armcap_P); |
| if ((env = getenv("OPENSSL_armcap")) != NULL) |
| BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), |
| sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), |
| " env:%s", env); |
| # elif defined(__s390__) || defined(__s390x__) |
| const char *env; |
| |
| BIO_snprintf(ossl_cpu_info_str, sizeof(ossl_cpu_info_str), |
| CPUINFO_PREFIX "OPENSSL_s390xcap=" |
| "stfle:0x%llx:0x%llx:0x%llx:0x%llx:" |
| "kimd:0x%llx:0x%llx:" |
| "klmd:0x%llx:0x%llx:" |
| "km:0x%llx:0x%llx:" |
| "kmc:0x%llx:0x%llx:" |
| "kmac:0x%llx:0x%llx:" |
| "kmctr:0x%llx:0x%llx:" |
| "kmo:0x%llx:0x%llx:" |
| "kmf:0x%llx:0x%llx:" |
| "prno:0x%llx:0x%llx:" |
| "kma:0x%llx:0x%llx:" |
| "pcc:0x%llx:0x%llx:" |
| "kdsa:0x%llx:0x%llx", |
| OPENSSL_s390xcap_P.stfle[0], OPENSSL_s390xcap_P.stfle[1], |
| OPENSSL_s390xcap_P.stfle[2], OPENSSL_s390xcap_P.stfle[3], |
| OPENSSL_s390xcap_P.kimd[0], OPENSSL_s390xcap_P.kimd[1], |
| OPENSSL_s390xcap_P.klmd[0], OPENSSL_s390xcap_P.klmd[1], |
| OPENSSL_s390xcap_P.km[0], OPENSSL_s390xcap_P.km[1], |
| OPENSSL_s390xcap_P.kmc[0], OPENSSL_s390xcap_P.kmc[1], |
| OPENSSL_s390xcap_P.kmac[0], OPENSSL_s390xcap_P.kmac[1], |
| OPENSSL_s390xcap_P.kmctr[0], OPENSSL_s390xcap_P.kmctr[1], |
| OPENSSL_s390xcap_P.kmo[0], OPENSSL_s390xcap_P.kmo[1], |
| OPENSSL_s390xcap_P.kmf[0], OPENSSL_s390xcap_P.kmf[1], |
| OPENSSL_s390xcap_P.prno[0], OPENSSL_s390xcap_P.prno[1], |
| OPENSSL_s390xcap_P.kma[0], OPENSSL_s390xcap_P.kma[1], |
| OPENSSL_s390xcap_P.pcc[0], OPENSSL_s390xcap_P.pcc[1], |
| OPENSSL_s390xcap_P.kdsa[0], OPENSSL_s390xcap_P.kdsa[1]); |
| if ((env = getenv("OPENSSL_s390xcap")) != NULL) |
| BIO_snprintf(ossl_cpu_info_str + strlen(ossl_cpu_info_str), |
| sizeof(ossl_cpu_info_str) - strlen(ossl_cpu_info_str), |
| " env:%s", env); |
| # endif |
| #endif |
| |
| { |
| static char seeds[512] = ""; |
| |
| #define add_seeds_string(str) \ |
| do { \ |
| if (seeds[0] != '\0') \ |
| OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ |
| OPENSSL_strlcat(seeds, str, sizeof(seeds)); \ |
| } while (0) |
| #define add_seeds_stringlist(label, strlist) \ |
| do { \ |
| add_seeds_string(label "("); \ |
| { \ |
| const char *dev[] = { strlist, NULL }; \ |
| const char **p; \ |
| int first = 1; \ |
| \ |
| for (p = dev; *p != NULL; p++) { \ |
| if (!first) \ |
| OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ |
| first = 0; \ |
| OPENSSL_strlcat(seeds, *p, sizeof(seeds)); \ |
| } \ |
| } \ |
| OPENSSL_strlcat(seeds, ")", sizeof(seeds)); \ |
| } while (0) |
| |
| #ifdef OPENSSL_RAND_SEED_NONE |
| add_seeds_string("none"); |
| #endif |
| #ifdef OPENSSL_RAND_SEED_RTDSC |
| add_seeds_string("stdsc"); |
| #endif |
| #ifdef OPENSSL_RAND_SEED_RDCPU |
| # ifdef __aarch64__ |
| add_seeds_string("rndr ( rndrrs rndr )"); |
| # else |
| add_seeds_string("rdrand ( rdseed rdrand )"); |
| # endif |
| #endif |
| #ifdef OPENSSL_RAND_SEED_LIBRANDOM |
| add_seeds_string("C-library-random"); |
| #endif |
| #ifdef OPENSSL_RAND_SEED_GETRANDOM |
| add_seeds_string("getrandom-syscall"); |
| #endif |
| #ifdef OPENSSL_RAND_SEED_DEVRANDOM |
| add_seeds_stringlist("random-device", DEVRANDOM); |
| #endif |
| #ifdef OPENSSL_RAND_SEED_EGD |
| add_seeds_stringlist("EGD", DEVRANDOM_EGD); |
| #endif |
| #ifdef OPENSSL_RAND_SEED_OS |
| add_seeds_string("os-specific"); |
| #endif |
| seed_sources = seeds; |
| } |
| return 1; |
| } |
| |
| const char *OPENSSL_info(int t) |
| { |
| /* |
| * We don't care about the result. Worst case scenario, the strings |
| * won't be initialised, i.e. remain NULL, which means that the info |
| * isn't available anyway... |
| */ |
| (void)RUN_ONCE(&init_info, init_info_strings); |
| |
| switch (t) { |
| case OPENSSL_INFO_CONFIG_DIR: |
| return OPENSSLDIR; |
| case OPENSSL_INFO_ENGINES_DIR: |
| return ENGINESDIR; |
| case OPENSSL_INFO_MODULES_DIR: |
| return MODULESDIR; |
| case OPENSSL_INFO_DSO_EXTENSION: |
| return DSO_EXTENSION; |
| case OPENSSL_INFO_DIR_FILENAME_SEPARATOR: |
| #if defined(_WIN32) |
| return "\\"; |
| #elif defined(__VMS) |
| return ""; |
| #else /* Assume POSIX */ |
| return "/"; |
| #endif |
| case OPENSSL_INFO_LIST_SEPARATOR: |
| { |
| static const char list_sep[] = { LIST_SEPARATOR_CHAR, '\0' }; |
| return list_sep; |
| } |
| case OPENSSL_INFO_SEED_SOURCE: |
| return seed_sources; |
| case OPENSSL_INFO_CPU_SETTINGS: |
| /* |
| * If successfully initialized, ossl_cpu_info_str will start |
| * with CPUINFO_PREFIX, if failed it will be an empty string. |
| * Strip away the CPUINFO_PREFIX which we don't need here. |
| */ |
| if (ossl_cpu_info_str[0] != '\0') |
| return ossl_cpu_info_str + strlen(CPUINFO_PREFIX); |
| break; |
| default: |
| break; |
| } |
| /* Not an error */ |
| return NULL; |
| } |