Add basic RISC-V cpuid and OPENSSL_riscvcap
RISC-V cpuid implementation allows bitmanip extensions Zb[abcs] to
be enabled at runtime using OPENSSL_riscvcap environment variable.
For example, to specify 64-bit RISC-V with the G,C,Zba,Zbb,Zbc
extensions, one could write: OPENSSL_riscvcap="rv64gc_zba_zbb_zbc"
Architecture string parsing is still very primitive, but can be
expanded in the future. Currently, only bitmanip extensions Zba, Zbb,
Zbc and Zbs are supported.
Includes implementation of constant-time CRYPTO_memcmp in riscv64 asm,
as well as OPENSSL_cleanse. Assembly implementations are written using
perlasm.
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Signed-off-by: Henry Brausen <henry.brausen@vrull.eu>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17640)
2022-01-28 16:28:52 +08:00
|
|
|
/*
|
2024-09-05 15:35:49 +08:00
|
|
|
* Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
|
Add basic RISC-V cpuid and OPENSSL_riscvcap
RISC-V cpuid implementation allows bitmanip extensions Zb[abcs] to
be enabled at runtime using OPENSSL_riscvcap environment variable.
For example, to specify 64-bit RISC-V with the G,C,Zba,Zbb,Zbc
extensions, one could write: OPENSSL_riscvcap="rv64gc_zba_zbb_zbc"
Architecture string parsing is still very primitive, but can be
expanded in the future. Currently, only bitmanip extensions Zba, Zbb,
Zbc and Zbs are supported.
Includes implementation of constant-time CRYPTO_memcmp in riscv64 asm,
as well as OPENSSL_cleanse. Assembly implementations are written using
perlasm.
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Signed-off-by: Henry Brausen <henry.brausen@vrull.eu>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17640)
2022-01-28 16:28:52 +08:00
|
|
|
*
|
|
|
|
* 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 <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <openssl/crypto.h>
|
|
|
|
#include "internal/cryptlib.h"
|
|
|
|
|
|
|
|
#define OPENSSL_RISCVCAP_IMPL
|
|
|
|
#include "crypto/riscv_arch.h"
|
|
|
|
|
2024-04-17 17:21:53 +08:00
|
|
|
#ifdef OSSL_RISCV_HWPROBE
|
|
|
|
# include <unistd.h>
|
|
|
|
# include <sys/syscall.h>
|
|
|
|
# include <asm/hwprobe.h>
|
|
|
|
#endif
|
|
|
|
|
2023-02-14 13:22:03 +08:00
|
|
|
extern size_t riscv_vlen_asm(void);
|
|
|
|
|
Add basic RISC-V cpuid and OPENSSL_riscvcap
RISC-V cpuid implementation allows bitmanip extensions Zb[abcs] to
be enabled at runtime using OPENSSL_riscvcap environment variable.
For example, to specify 64-bit RISC-V with the G,C,Zba,Zbb,Zbc
extensions, one could write: OPENSSL_riscvcap="rv64gc_zba_zbb_zbc"
Architecture string parsing is still very primitive, but can be
expanded in the future. Currently, only bitmanip extensions Zba, Zbb,
Zbc and Zbs are supported.
Includes implementation of constant-time CRYPTO_memcmp in riscv64 asm,
as well as OPENSSL_cleanse. Assembly implementations are written using
perlasm.
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Signed-off-by: Henry Brausen <henry.brausen@vrull.eu>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17640)
2022-01-28 16:28:52 +08:00
|
|
|
static void parse_env(const char *envstr);
|
|
|
|
static void strtoupper(char *str);
|
|
|
|
|
2023-02-14 13:22:03 +08:00
|
|
|
static size_t vlen = 0;
|
|
|
|
|
Add basic RISC-V cpuid and OPENSSL_riscvcap
RISC-V cpuid implementation allows bitmanip extensions Zb[abcs] to
be enabled at runtime using OPENSSL_riscvcap environment variable.
For example, to specify 64-bit RISC-V with the G,C,Zba,Zbb,Zbc
extensions, one could write: OPENSSL_riscvcap="rv64gc_zba_zbb_zbc"
Architecture string parsing is still very primitive, but can be
expanded in the future. Currently, only bitmanip extensions Zba, Zbb,
Zbc and Zbs are supported.
Includes implementation of constant-time CRYPTO_memcmp in riscv64 asm,
as well as OPENSSL_cleanse. Assembly implementations are written using
perlasm.
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Signed-off-by: Henry Brausen <henry.brausen@vrull.eu>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17640)
2022-01-28 16:28:52 +08:00
|
|
|
uint32_t OPENSSL_rdtsc(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void strtoupper(char *str)
|
|
|
|
{
|
|
|
|
for (char *x = str; *x; ++x)
|
Avoid undefined behaviour with the <ctype.h> functions.
fix https://github.com/openssl/openssl/issues/25112
As defined in the C standard:
In all cases the argument is an int, the value of which shall
be representable as an unsigned char or shall equal the value
of the macro EOF. If the argument has any other value, the
behavior is undefined.
This is because they're designed to work with the int values returned
by getc or fgetc; they need extra work to handle a char value.
If EOF is -1 (as it almost always is), with 8-bit bytes, the allowed
inputs to the ctype.h functions are:
{-1, 0, 1, 2, 3, ..., 255}.
However, on platforms where char is signed, such as x86 with the
usual ABI, code like
char *p = ...;
... isspace(*p) ...
may pass in values in the range:
{-128, -127, -126, ..., -2, -1, 0, 1, ..., 127}.
This has two problems:
1. Inputs in the set {-128, -127, -126, ..., -2} are forbidden.
2. The non-EOF byte 0xff is conflated with the value EOF = -1, so
even though the input is not forbidden, it may give the wrong
answer.
Casting char inputs to unsigned char first works around this, by
mapping the (non-EOF character) range {-128, -127, ..., -1} to {128,
129, ..., 255}, leaving no collisions with EOF. So the above
fragment needs to be:
char *p = ...;
... isspace((unsigned char)*p) ...
This patch inserts unsigned char casts where necessary. Most of the
cases I changed, I compile-tested using -Wchar-subscripts -Werror on
NetBSD, which defines the ctype.h functions as macros so that they
trigger the warning when the argument has type char. The exceptions
are under #ifdef __VMS or #ifdef _WIN32. I left alone calls where
the input is int where the cast would obviously be wrong; and I left
alone calls where the input is already unsigned char so the cast is
unnecessary.
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25113)
2023-03-29 13:48:44 +08:00
|
|
|
*x = toupper((unsigned char)*x);
|
Add basic RISC-V cpuid and OPENSSL_riscvcap
RISC-V cpuid implementation allows bitmanip extensions Zb[abcs] to
be enabled at runtime using OPENSSL_riscvcap environment variable.
For example, to specify 64-bit RISC-V with the G,C,Zba,Zbb,Zbc
extensions, one could write: OPENSSL_riscvcap="rv64gc_zba_zbb_zbc"
Architecture string parsing is still very primitive, but can be
expanded in the future. Currently, only bitmanip extensions Zba, Zbb,
Zbc and Zbs are supported.
Includes implementation of constant-time CRYPTO_memcmp in riscv64 asm,
as well as OPENSSL_cleanse. Assembly implementations are written using
perlasm.
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Signed-off-by: Henry Brausen <henry.brausen@vrull.eu>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17640)
2022-01-28 16:28:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* parse_env() parses a RISC-V architecture string. An example of such a string
|
|
|
|
* is "rv64gc_zba_zbb_zbc_zbs". Currently, the rv64gc part is ignored
|
|
|
|
* and we simply search for "_[extension]" in the arch string to see if we
|
|
|
|
* should enable a given extension.
|
|
|
|
*/
|
|
|
|
#define BUFLEN 256
|
|
|
|
static void parse_env(const char *envstr)
|
|
|
|
{
|
|
|
|
char envstrupper[BUFLEN];
|
|
|
|
char buf[BUFLEN];
|
|
|
|
|
|
|
|
/* Convert env str to all uppercase */
|
|
|
|
OPENSSL_strlcpy(envstrupper, envstr, sizeof(envstrupper));
|
|
|
|
strtoupper(envstrupper);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < kRISCVNumCaps; ++i) {
|
|
|
|
/* Prefix capability with underscore in preparation for search */
|
|
|
|
BIO_snprintf(buf, BUFLEN, "_%s", RISCV_capabilities[i].name);
|
|
|
|
if (strstr(envstrupper, buf) != NULL) {
|
|
|
|
/* Match, set relevant bit in OPENSSL_riscvcap_P[] */
|
|
|
|
OPENSSL_riscvcap_P[RISCV_capabilities[i].index] |=
|
|
|
|
(1 << RISCV_capabilities[i].bit_offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-17 17:21:53 +08:00
|
|
|
#ifdef OSSL_RISCV_HWPROBE
|
|
|
|
static long riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count,
|
|
|
|
size_t cpu_count, unsigned long *cpus,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
return syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_count, cpus, flags);
|
|
|
|
}
|
|
|
|
|
2024-05-12 15:18:44 +08:00
|
|
|
static void hwprobe_to_cap(void)
|
2024-04-17 17:21:53 +08:00
|
|
|
{
|
|
|
|
long ret;
|
|
|
|
struct riscv_hwprobe pairs[OSSL_RISCV_HWPROBE_PAIR_COUNT] = {
|
|
|
|
OSSL_RISCV_HWPROBE_PAIR_CONTENT
|
|
|
|
};
|
|
|
|
|
|
|
|
ret = riscv_hwprobe(pairs, OSSL_RISCV_HWPROBE_PAIR_COUNT, 0, NULL, 0);
|
|
|
|
/* if hwprobe syscall does not exist, ret would be -ENOSYS */
|
|
|
|
if (ret == 0) {
|
|
|
|
for (size_t i = 0; i < kRISCVNumCaps; ++i) {
|
|
|
|
for (size_t j = 0; j != OSSL_RISCV_HWPROBE_PAIR_COUNT; ++j) {
|
|
|
|
if (pairs[j].key == RISCV_capabilities[i].hwprobe_key
|
|
|
|
&& (pairs[j].value & RISCV_capabilities[i].hwprobe_value)
|
|
|
|
!= 0)
|
|
|
|
/* Match, set relevant bit in OPENSSL_riscvcap_P[] */
|
|
|
|
OPENSSL_riscvcap_P[RISCV_capabilities[i].index] |=
|
|
|
|
(1 << RISCV_capabilities[i].bit_offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* OSSL_RISCV_HWPROBE */
|
|
|
|
|
2023-02-14 13:22:03 +08:00
|
|
|
size_t riscv_vlen(void)
|
|
|
|
{
|
|
|
|
return vlen;
|
|
|
|
}
|
|
|
|
|
Add basic RISC-V cpuid and OPENSSL_riscvcap
RISC-V cpuid implementation allows bitmanip extensions Zb[abcs] to
be enabled at runtime using OPENSSL_riscvcap environment variable.
For example, to specify 64-bit RISC-V with the G,C,Zba,Zbb,Zbc
extensions, one could write: OPENSSL_riscvcap="rv64gc_zba_zbb_zbc"
Architecture string parsing is still very primitive, but can be
expanded in the future. Currently, only bitmanip extensions Zba, Zbb,
Zbc and Zbs are supported.
Includes implementation of constant-time CRYPTO_memcmp in riscv64 asm,
as well as OPENSSL_cleanse. Assembly implementations are written using
perlasm.
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Signed-off-by: Henry Brausen <henry.brausen@vrull.eu>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17640)
2022-01-28 16:28:52 +08:00
|
|
|
# if defined(__GNUC__) && __GNUC__>=2
|
|
|
|
__attribute__ ((constructor))
|
|
|
|
# endif
|
|
|
|
void OPENSSL_cpuid_setup(void)
|
|
|
|
{
|
|
|
|
char *e;
|
|
|
|
static int trigger = 0;
|
|
|
|
|
|
|
|
if (trigger != 0)
|
|
|
|
return;
|
|
|
|
trigger = 1;
|
|
|
|
|
|
|
|
if ((e = getenv("OPENSSL_riscvcap"))) {
|
|
|
|
parse_env(e);
|
2023-02-14 13:22:03 +08:00
|
|
|
}
|
2024-04-17 17:21:53 +08:00
|
|
|
#ifdef OSSL_RISCV_HWPROBE
|
|
|
|
else {
|
|
|
|
hwprobe_to_cap();
|
|
|
|
}
|
|
|
|
#endif
|
2023-02-14 13:22:03 +08:00
|
|
|
|
|
|
|
if (RISCV_HAS_V()) {
|
|
|
|
vlen = riscv_vlen_asm();
|
Add basic RISC-V cpuid and OPENSSL_riscvcap
RISC-V cpuid implementation allows bitmanip extensions Zb[abcs] to
be enabled at runtime using OPENSSL_riscvcap environment variable.
For example, to specify 64-bit RISC-V with the G,C,Zba,Zbb,Zbc
extensions, one could write: OPENSSL_riscvcap="rv64gc_zba_zbb_zbc"
Architecture string parsing is still very primitive, but can be
expanded in the future. Currently, only bitmanip extensions Zba, Zbb,
Zbc and Zbs are supported.
Includes implementation of constant-time CRYPTO_memcmp in riscv64 asm,
as well as OPENSSL_cleanse. Assembly implementations are written using
perlasm.
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Signed-off-by: Henry Brausen <henry.brausen@vrull.eu>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17640)
2022-01-28 16:28:52 +08:00
|
|
|
}
|
|
|
|
}
|