sock: Add ktls and tls_version to spdk_sock_opts
See https://docs.kernel.org/networking/tls-offload.html See https://www.openssl.org/docs/man3.0/man3/SSL_set_options.html Change-Id: I2fb433cbc34061cb03e1591bb0b47063fcafc68c Signed-off-by: Boris Glimcher <Boris.Glimcher@emc.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/13071 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
This commit is contained in:
parent
a83dc0546f
commit
7104c8332d
@ -17,6 +17,10 @@ in the future.
|
|||||||
Add num_md_pages_per_cluster_ratio parameter to the bdev_lvol_create_lvstore RPC.
|
Add num_md_pages_per_cluster_ratio parameter to the bdev_lvol_create_lvstore RPC.
|
||||||
Calculate num_md_pages from num_md_pages_per_cluster_ratio, and pass it to spdk_bs_opts.
|
Calculate num_md_pages from num_md_pages_per_cluster_ratio, and pass it to spdk_bs_opts.
|
||||||
|
|
||||||
|
### rpc
|
||||||
|
|
||||||
|
New options `ktls` and `tls_version` were added to the `spdk_sock_opts` structure.
|
||||||
|
|
||||||
## v22.05
|
## v22.05
|
||||||
|
|
||||||
### sock
|
### sock
|
||||||
|
@ -24,6 +24,8 @@ static char *g_sock_impl_name;
|
|||||||
static int g_port;
|
static int g_port;
|
||||||
static bool g_is_server;
|
static bool g_is_server;
|
||||||
static int g_zcopy;
|
static int g_zcopy;
|
||||||
|
static int g_ktls;
|
||||||
|
static int g_tls_version;
|
||||||
static bool g_verbose;
|
static bool g_verbose;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -36,6 +38,8 @@ struct hello_context_t {
|
|||||||
char *sock_impl_name;
|
char *sock_impl_name;
|
||||||
int port;
|
int port;
|
||||||
int zcopy;
|
int zcopy;
|
||||||
|
int ktls;
|
||||||
|
int tls_version;
|
||||||
|
|
||||||
bool verbose;
|
bool verbose;
|
||||||
int bytes_in;
|
int bytes_in;
|
||||||
@ -61,6 +65,9 @@ hello_sock_usage(void)
|
|||||||
printf(" -P port port number\n");
|
printf(" -P port port number\n");
|
||||||
printf(" -N sock_impl socket implementation, e.g., -N posix or -N uring\n");
|
printf(" -N sock_impl socket implementation, e.g., -N posix or -N uring\n");
|
||||||
printf(" -S start in server mode\n");
|
printf(" -S start in server mode\n");
|
||||||
|
printf(" -T tls_ver TLS version, e.g., -T 12 or -T 13. If omitted, auto-negotiation will take place\n");
|
||||||
|
printf(" -k disable KTLS for the given sock implementation (default)\n");
|
||||||
|
printf(" -K enable KTLS for the given sock implementation\n");
|
||||||
printf(" -V print out additional informations\n");
|
printf(" -V print out additional informations\n");
|
||||||
printf(" -z disable zero copy send for the given sock implementation\n");
|
printf(" -z disable zero copy send for the given sock implementation\n");
|
||||||
printf(" -Z enable zero copy send for the given sock implementation\n");
|
printf(" -Z enable zero copy send for the given sock implementation\n");
|
||||||
@ -89,6 +96,19 @@ hello_sock_parse_arg(int ch, char *arg)
|
|||||||
case 'S':
|
case 'S':
|
||||||
g_is_server = 1;
|
g_is_server = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'K':
|
||||||
|
g_ktls = 1;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
g_ktls = 0;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
g_tls_version = spdk_strtol(arg, 10);
|
||||||
|
if (g_tls_version < 0) {
|
||||||
|
fprintf(stderr, "Invalid TLS version\n");
|
||||||
|
return g_tls_version;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
g_verbose = true;
|
g_verbose = true;
|
||||||
break;
|
break;
|
||||||
@ -203,6 +223,8 @@ hello_sock_connect(struct hello_context_t *ctx)
|
|||||||
opts.opts_size = sizeof(opts);
|
opts.opts_size = sizeof(opts);
|
||||||
spdk_sock_get_default_opts(&opts);
|
spdk_sock_get_default_opts(&opts);
|
||||||
opts.zcopy = ctx->zcopy;
|
opts.zcopy = ctx->zcopy;
|
||||||
|
opts.ktls = ctx->ktls;
|
||||||
|
opts.tls_version = ctx->tls_version;
|
||||||
|
|
||||||
SPDK_NOTICELOG("Connecting to the server on %s:%d with sock_impl(%s)\n", ctx->host, ctx->port,
|
SPDK_NOTICELOG("Connecting to the server on %s:%d with sock_impl(%s)\n", ctx->host, ctx->port,
|
||||||
ctx->sock_impl_name);
|
ctx->sock_impl_name);
|
||||||
@ -339,6 +361,8 @@ hello_sock_listen(struct hello_context_t *ctx)
|
|||||||
opts.opts_size = sizeof(opts);
|
opts.opts_size = sizeof(opts);
|
||||||
spdk_sock_get_default_opts(&opts);
|
spdk_sock_get_default_opts(&opts);
|
||||||
opts.zcopy = ctx->zcopy;
|
opts.zcopy = ctx->zcopy;
|
||||||
|
opts.ktls = ctx->ktls;
|
||||||
|
opts.tls_version = ctx->tls_version;
|
||||||
|
|
||||||
ctx->sock = spdk_sock_listen_ext(ctx->host, ctx->port, ctx->sock_impl_name, &opts);
|
ctx->sock = spdk_sock_listen_ext(ctx->host, ctx->port, ctx->sock_impl_name, &opts);
|
||||||
if (ctx->sock == NULL) {
|
if (ctx->sock == NULL) {
|
||||||
@ -407,7 +431,7 @@ main(int argc, char **argv)
|
|||||||
opts.name = "hello_sock";
|
opts.name = "hello_sock";
|
||||||
opts.shutdown_cb = hello_sock_shutdown_cb;
|
opts.shutdown_cb = hello_sock_shutdown_cb;
|
||||||
|
|
||||||
if ((rc = spdk_app_parse_args(argc, argv, &opts, "H:N:P:SVzZ", NULL, hello_sock_parse_arg,
|
if ((rc = spdk_app_parse_args(argc, argv, &opts, "H:kKN:P:ST:VzZ", NULL, hello_sock_parse_arg,
|
||||||
hello_sock_usage)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
|
hello_sock_usage)) != SPDK_APP_PARSE_ARGS_SUCCESS) {
|
||||||
exit(rc);
|
exit(rc);
|
||||||
}
|
}
|
||||||
@ -416,6 +440,8 @@ main(int argc, char **argv)
|
|||||||
hello_context.sock_impl_name = g_sock_impl_name;
|
hello_context.sock_impl_name = g_sock_impl_name;
|
||||||
hello_context.port = g_port;
|
hello_context.port = g_port;
|
||||||
hello_context.zcopy = g_zcopy;
|
hello_context.zcopy = g_zcopy;
|
||||||
|
hello_context.ktls = g_ktls;
|
||||||
|
hello_context.tls_version = g_tls_version;
|
||||||
hello_context.verbose = g_verbose;
|
hello_context.verbose = g_verbose;
|
||||||
|
|
||||||
rc = spdk_app_start(&opts, hello_start, &hello_context);
|
rc = spdk_app_start(&opts, hello_start, &hello_context);
|
||||||
|
@ -65,6 +65,10 @@ enum spdk_placement_mode {
|
|||||||
PLACEMENT_MARK,
|
PLACEMENT_MARK,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SPDK_TLS_VERSION_1_1 11
|
||||||
|
#define SPDK_TLS_VERSION_1_2 12
|
||||||
|
#define SPDK_TLS_VERSION_1_3 13
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SPDK socket implementation options.
|
* SPDK socket implementation options.
|
||||||
*
|
*
|
||||||
@ -150,6 +154,17 @@ struct spdk_sock_opts {
|
|||||||
* Time in msec to wait ack until connection is closed forcefully.
|
* Time in msec to wait ack until connection is closed forcefully.
|
||||||
*/
|
*/
|
||||||
uint32_t ack_timeout;
|
uint32_t ack_timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TLS protocol version. Used by posix socket module.
|
||||||
|
*/
|
||||||
|
uint32_t tls_version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to enable or disable KTLS for ssl posix socket module.
|
||||||
|
*/
|
||||||
|
bool ktls;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
||||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||||
|
|
||||||
SO_VER := 6
|
SO_VER := 7
|
||||||
SO_MINOR := 0
|
SO_MINOR := 0
|
||||||
|
|
||||||
C_SRCS = sock.c sock_rpc.c
|
C_SRCS = sock.c sock_rpc.c
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#define SPDK_SOCK_DEFAULT_PRIORITY 0
|
#define SPDK_SOCK_DEFAULT_PRIORITY 0
|
||||||
#define SPDK_SOCK_DEFAULT_ZCOPY true
|
#define SPDK_SOCK_DEFAULT_ZCOPY true
|
||||||
#define SPDK_SOCK_DEFAULT_ACK_TIMEOUT 0
|
#define SPDK_SOCK_DEFAULT_ACK_TIMEOUT 0
|
||||||
|
#define SPDK_SOCK_DEFAULT_TLS_VERSION 0
|
||||||
|
#define SPDK_SOCK_DEFAULT_KTLS false
|
||||||
|
|
||||||
#define SPDK_SOCK_OPTS_FIELD_OK(opts, field) (offsetof(struct spdk_sock_opts, field) + sizeof(opts->field) <= (opts->opts_size))
|
#define SPDK_SOCK_OPTS_FIELD_OK(opts, field) (offsetof(struct spdk_sock_opts, field) + sizeof(opts->field) <= (opts->opts_size))
|
||||||
|
|
||||||
@ -245,6 +247,14 @@ spdk_sock_get_default_opts(struct spdk_sock_opts *opts)
|
|||||||
if (SPDK_SOCK_OPTS_FIELD_OK(opts, ack_timeout)) {
|
if (SPDK_SOCK_OPTS_FIELD_OK(opts, ack_timeout)) {
|
||||||
opts->ack_timeout = SPDK_SOCK_DEFAULT_ACK_TIMEOUT;
|
opts->ack_timeout = SPDK_SOCK_DEFAULT_ACK_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SPDK_SOCK_OPTS_FIELD_OK(opts, tls_version)) {
|
||||||
|
opts->tls_version = SPDK_SOCK_DEFAULT_TLS_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SPDK_SOCK_OPTS_FIELD_OK(opts, ktls)) {
|
||||||
|
opts->ktls = SPDK_SOCK_DEFAULT_KTLS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -273,6 +283,14 @@ sock_init_opts(struct spdk_sock_opts *opts, struct spdk_sock_opts *opts_user)
|
|||||||
if (SPDK_SOCK_OPTS_FIELD_OK(opts, ack_timeout)) {
|
if (SPDK_SOCK_OPTS_FIELD_OK(opts, ack_timeout)) {
|
||||||
opts->ack_timeout = opts_user->ack_timeout;
|
opts->ack_timeout = opts_user->ack_timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SPDK_SOCK_OPTS_FIELD_OK(opts, tls_version)) {
|
||||||
|
opts->tls_version = opts_user->tls_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SPDK_SOCK_OPTS_FIELD_OK(opts, ktls)) {
|
||||||
|
opts->ktls = opts_user->ktls;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spdk_sock *
|
struct spdk_sock *
|
||||||
|
@ -506,9 +506,14 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SSL_CTX *
|
static SSL_CTX *
|
||||||
posix_sock_create_ssl_context(const SSL_METHOD *method)
|
posix_sock_create_ssl_context(const SSL_METHOD *method, struct spdk_sock_opts *opts)
|
||||||
{
|
{
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
|
int tls_version = 0;
|
||||||
|
bool ktls_enabled = false;
|
||||||
|
#ifdef SSL_OP_ENABLE_KTLS
|
||||||
|
long options;
|
||||||
|
#endif
|
||||||
|
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
OpenSSL_add_all_algorithms();
|
OpenSSL_add_all_algorithms();
|
||||||
@ -516,11 +521,59 @@ posix_sock_create_ssl_context(const SSL_METHOD *method)
|
|||||||
/* Produce a SSL CTX in SSL V2 and V3 standards compliant way */
|
/* Produce a SSL CTX in SSL V2 and V3 standards compliant way */
|
||||||
ctx = SSL_CTX_new(method);
|
ctx = SSL_CTX_new(method);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
SPDK_ERRLOG("SSL_CTX_new() failed, errno = %d\n", errno);
|
SPDK_ERRLOG("SSL_CTX_new() failed, msg = %s\n", ERR_error_string(ERR_peek_last_error(), NULL));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
SPDK_DEBUGLOG(sock_posix, "SSL context created\n");
|
SPDK_DEBUGLOG(sock_posix, "SSL context created\n");
|
||||||
|
|
||||||
|
switch (opts->tls_version) {
|
||||||
|
case 0:
|
||||||
|
/* auto-negotioation */
|
||||||
|
break;
|
||||||
|
case SPDK_TLS_VERSION_1_1:
|
||||||
|
tls_version = TLS1_1_VERSION;
|
||||||
|
break;
|
||||||
|
case SPDK_TLS_VERSION_1_2:
|
||||||
|
tls_version = TLS1_2_VERSION;
|
||||||
|
break;
|
||||||
|
case SPDK_TLS_VERSION_1_3:
|
||||||
|
tls_version = TLS1_3_VERSION;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SPDK_ERRLOG("Incorrect TLS version provided: %d\n", opts->tls_version);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tls_version) {
|
||||||
|
SPDK_DEBUGLOG(sock_posix, "Hardening TLS version to '%d'='0x%X'\n", opts->tls_version, tls_version);
|
||||||
|
if (!SSL_CTX_set_min_proto_version(ctx, tls_version)) {
|
||||||
|
SPDK_ERRLOG("Unable to set Min TLS version to '%d'='0x%X\n", opts->tls_version, tls_version);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (!SSL_CTX_set_max_proto_version(ctx, tls_version)) {
|
||||||
|
SPDK_ERRLOG("Unable to set Max TLS version to '%d'='0x%X\n", opts->tls_version, tls_version);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opts->ktls) {
|
||||||
|
SPDK_DEBUGLOG(sock_posix, "Enabling kTLS offload\n");
|
||||||
|
#ifdef SSL_OP_ENABLE_KTLS
|
||||||
|
options = SSL_CTX_set_options(ctx, SSL_OP_ENABLE_KTLS);
|
||||||
|
ktls_enabled = options & SSL_OP_ENABLE_KTLS;
|
||||||
|
#else
|
||||||
|
ktls_enabled = false;
|
||||||
|
#endif
|
||||||
|
if (!ktls_enabled) {
|
||||||
|
SPDK_ERRLOG("Unable to set kTLS offload via SSL_CTX_set_options(). Configure openssl with 'enable-ktls'\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
|
|
||||||
|
err:
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSL *
|
static SSL *
|
||||||
@ -532,7 +585,7 @@ ssl_sock_connect_loop(SSL_CTX *ctx, int fd)
|
|||||||
|
|
||||||
ssl = SSL_new(ctx);
|
ssl = SSL_new(ctx);
|
||||||
if (!ssl) {
|
if (!ssl) {
|
||||||
SPDK_ERRLOG("SSL_new() failed, errno = %d\n", errno);
|
SPDK_ERRLOG("SSL_new() failed, msg = %s\n", ERR_error_string(ERR_peek_last_error(), NULL));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
SSL_set_fd(ssl, fd);
|
SSL_set_fd(ssl, fd);
|
||||||
@ -570,7 +623,7 @@ ssl_sock_accept_loop(SSL_CTX *ctx, int fd)
|
|||||||
|
|
||||||
ssl = SSL_new(ctx);
|
ssl = SSL_new(ctx);
|
||||||
if (!ssl) {
|
if (!ssl) {
|
||||||
SPDK_ERRLOG("SSL_new() failed, errno = %d\n", errno);
|
SPDK_ERRLOG("SSL_new() failed, msg = %s\n", ERR_error_string(ERR_peek_last_error(), NULL));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
SSL_set_fd(ssl, fd);
|
SSL_set_fd(ssl, fd);
|
||||||
@ -742,7 +795,7 @@ retry:
|
|||||||
}
|
}
|
||||||
if (type == SPDK_SOCK_CREATE_LISTEN) {
|
if (type == SPDK_SOCK_CREATE_LISTEN) {
|
||||||
if (enable_ssl) {
|
if (enable_ssl) {
|
||||||
ctx = posix_sock_create_ssl_context(TLS_server_method());
|
ctx = posix_sock_create_ssl_context(TLS_server_method(), opts);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
SPDK_ERRLOG("posix_sock_create_ssl_context() failed, errno = %d\n", errno);
|
SPDK_ERRLOG("posix_sock_create_ssl_context() failed, errno = %d\n", errno);
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -791,7 +844,7 @@ retry:
|
|||||||
}
|
}
|
||||||
enable_zcopy_impl_opts = g_spdk_posix_sock_impl_opts.enable_zerocopy_send_client;
|
enable_zcopy_impl_opts = g_spdk_posix_sock_impl_opts.enable_zerocopy_send_client;
|
||||||
if (enable_ssl) {
|
if (enable_ssl) {
|
||||||
ctx = posix_sock_create_ssl_context(TLS_client_method());
|
ctx = posix_sock_create_ssl_context(TLS_client_method(), opts);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
SPDK_ERRLOG("posix_sock_create_ssl_context() failed, errno = %d\n", errno);
|
SPDK_ERRLOG("posix_sock_create_ssl_context() failed, errno = %d\n", errno);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -131,6 +131,36 @@ if ! echo "$response" | grep -q "$message"; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# send message using hello_sock client using TLS 1.3
|
||||||
|
message="**MESSAGE:This is a test message from the hello_sock client with ssl using TLS 1.3**"
|
||||||
|
response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -T 13)
|
||||||
|
if ! echo "$response" | grep -q "$message"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# send message using hello_sock client using TLS 1.2
|
||||||
|
message="**MESSAGE:This is a test message from the hello_sock client with ssl using TLS 1.2**"
|
||||||
|
response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -T 12)
|
||||||
|
if ! echo "$response" | grep -q "$message"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# send message using hello_sock client using incorrect TLS 7
|
||||||
|
message="**MESSAGE:This is a test message from the hello_sock client with ssl using incorrect TLS 7**"
|
||||||
|
echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -T 7 && exit 1
|
||||||
|
|
||||||
|
# send message using hello_sock client with KTLS disabled
|
||||||
|
message="**MESSAGE:This is a test message from the hello_sock client with KTLS disabled**"
|
||||||
|
response=$(echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -k)
|
||||||
|
if ! echo "$response" | grep -q "$message"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# send message using hello_sock client with KTLS enabled
|
||||||
|
message="**MESSAGE:This is a test message from the hello_sock client with KTLS enabled**"
|
||||||
|
# UT infrastructure so far doesn't support new openssl-3 with this option, so expect a failure
|
||||||
|
echo $message | $HELLO_SOCK_APP -H $TARGET_IP -P $ISCSI_PORT -N "ssl" -K && exit 1
|
||||||
|
|
||||||
# send message using openssl client using TLS 1.3
|
# send message using openssl client using TLS 1.3
|
||||||
message="**MESSAGE:This is a test message from the openssl client using TLS 1.3**"
|
message="**MESSAGE:This is a test message from the openssl client using TLS 1.3**"
|
||||||
response=$( (
|
response=$( (
|
||||||
|
Loading…
Reference in New Issue
Block a user