Add core bio method for uadk_provider to correctly deal with file IO, otherwise the fseek() will be suspended.
Error log: [...] in lseek64 () from /usr/lib64/libc.so.6 [...] in _IO_file_seekoff () from /usr/lib64/libc.so.6 [...] in fseek () from /usr/lib64/libc.so.6 [...] in file_ctrl () from /usr/lib64/libcrypto.so.3 [...] in BIO_ctrl () from /usr/lib64/libcrypto.so.3 [...] in decoder_process () from /usr/lib64/libcrypto.so.3 [...] in OSSL_DECODER_from_bio () from /usr/lib64/libcrypto.so.3 [...] in file_load () from /usr/lib64/libcrypto.so.3 [...] in OSSL_STORE_load () from /usr/lib64/libcrypto.so.3 [...] in load_key_certs_crls_suppress () [...] in load_key_certs_crls () [...] in load_key () [...] in dgst_main () [...] in do_cmd () [...] in main ()
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/Makefile.am | 3 +- src/uadk_prov.h | 20 +++- src/uadk_prov_bio.c | 265 +++++++++++++++++++++++++++++++++++++++++++ src/uadk_prov_bio.h | 34 ++++++ src/uadk_prov_init.c | 69 +++++++++-- 5 files changed, 376 insertions(+), 15 deletions(-) create mode 100644 src/uadk_prov_bio.c create mode 100644 src/uadk_prov_bio.h
diff --git a/src/Makefile.am b/src/Makefile.am index 5911edb..fe57b9d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,7 +62,8 @@ endif #WD_KAE
uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ uadk_prov_digest.c uadk_prov_cipher.c \ - uadk_prov_rsa.c uadk_prov_dh.c + uadk_prov_rsa.c uadk_prov_dh.c \ + uadk_prov_bio.c
uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread diff --git a/src/uadk_prov.h b/src/uadk_prov.h index e5ac61f..508f113 100644 --- a/src/uadk_prov.h +++ b/src/uadk_prov.h @@ -88,10 +88,26 @@ struct ossl_provider_st { const OSSL_DISPATCH *dispatch; };
-struct uadk_prov_ctx { +typedef struct bio_method_st { + int type; + char *name; + int (*bwrite)(BIO *bio, const char *data, size_t datal, size_t *written); + int (*bwrite_old)(BIO *bio, const char *data, int datal); + int (*bread)(BIO *bio, char *data, size_t datal, size_t *read); + int (*bread_old)(BIO *bio, char *data, int datal); + int (*bputs)(BIO *bio, const char *buf); + int (*bgets)(BIO *bio, char *buf, int size); + long (*ctrl)(BIO *bio, int cmd, long larg, void *parg); + int (*create)(BIO *bio); + int (*destroy)(BIO *bio); + long (*callback_ctrl)(BIO *bio, int cmd, BIO_info_cb *fp); +} UADK_BIO_METHOD; + +typedef struct uadk_prov_ctx { const OSSL_CORE_HANDLE *handle; OSSL_LIB_CTX *libctx; -}; + UADK_BIO_METHOD *corebiometh; +} UADK_PROV_CTX;
static inline OSSL_LIB_CTX *prov_libctx_of(struct uadk_prov_ctx *ctx) { diff --git a/src/uadk_prov_bio.c b/src/uadk_prov_bio.c new file mode 100644 index 0000000..09383aa --- /dev/null +++ b/src/uadk_prov_bio.c @@ -0,0 +1,265 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright 2019-2021 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 <assert.h> +#include <openssl/core_dispatch.h> +#include <openssl/bio.h> +#include "uadk_prov_bio.h" + +/* Functions provided by bio */ +static OSSL_FUNC_BIO_new_file_fn *c_bio_new_file; +static OSSL_FUNC_BIO_new_membuf_fn *c_bio_new_membuf; +static OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex; +static OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex; +static OSSL_FUNC_BIO_gets_fn *c_bio_gets; +static OSSL_FUNC_BIO_puts_fn *c_bio_puts; +static OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl; +static OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref; +static OSSL_FUNC_BIO_free_fn *c_bio_free; +static OSSL_FUNC_BIO_vprintf_fn *c_bio_vprintf; + +int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) +{ + for (fns; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_BIO_NEW_FILE: + if (c_bio_new_file == NULL) + c_bio_new_file = OSSL_FUNC_BIO_new_file(fns); + break; + case OSSL_FUNC_BIO_NEW_MEMBUF: + if (c_bio_new_membuf == NULL) + c_bio_new_membuf = OSSL_FUNC_BIO_new_membuf(fns); + break; + case OSSL_FUNC_BIO_READ_EX: + if (c_bio_read_ex == NULL) + c_bio_read_ex = OSSL_FUNC_BIO_read_ex(fns); + break; + case OSSL_FUNC_BIO_WRITE_EX: + if (c_bio_write_ex == NULL) + c_bio_write_ex = OSSL_FUNC_BIO_write_ex(fns); + break; + case OSSL_FUNC_BIO_GETS: + if (c_bio_gets == NULL) + c_bio_gets = OSSL_FUNC_BIO_gets(fns); + break; + case OSSL_FUNC_BIO_PUTS: + if (c_bio_puts == NULL) + c_bio_puts = OSSL_FUNC_BIO_puts(fns); + break; + case OSSL_FUNC_BIO_CTRL: + if (c_bio_ctrl == NULL) + c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns); + break; + case OSSL_FUNC_BIO_UP_REF: + if (c_bio_up_ref == NULL) + c_bio_up_ref = OSSL_FUNC_BIO_up_ref(fns); + break; + case OSSL_FUNC_BIO_FREE: + if (c_bio_free == NULL) + c_bio_free = OSSL_FUNC_BIO_free(fns); + break; + case OSSL_FUNC_BIO_VPRINTF: + if (c_bio_vprintf == NULL) + c_bio_vprintf = OSSL_FUNC_BIO_vprintf(fns); + break; + } + } + + return 1; +} + +OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode) +{ + if (c_bio_new_file == NULL) + return NULL; + + return c_bio_new_file(filename, mode); +} + +OSSL_CORE_BIO *ossl_prov_bio_new_membuf(const char *filename, int len) +{ + if (c_bio_new_membuf == NULL) + return NULL; + + return c_bio_new_membuf(filename, len); +} + +int ossl_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len, + size_t *bytes_read) +{ + if (c_bio_read_ex == NULL) + return 0; + + return c_bio_read_ex(bio, data, data_len, bytes_read); +} + +int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len, + size_t *written) +{ + if (c_bio_write_ex == NULL) + return 0; + + return c_bio_write_ex(bio, data, data_len, written); +} + +int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size) +{ + if (c_bio_gets == NULL) + return -1; + + return c_bio_gets(bio, buf, size); +} + +int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str) +{ + if (c_bio_puts == NULL) + return -1; + + return c_bio_puts(bio, str); +} + +int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr) +{ + if (c_bio_ctrl == NULL) + return -1; + + return c_bio_ctrl(bio, cmd, num, ptr); +} + +int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio) +{ + if (c_bio_up_ref == NULL) + return 0; + + return c_bio_up_ref(bio); +} + +int ossl_prov_bio_free(OSSL_CORE_BIO *bio) +{ + if (c_bio_free == NULL) + return 0; + + return c_bio_free(bio); +} + +int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap) +{ + if (c_bio_vprintf == NULL) + return -1; + + return c_bio_vprintf(bio, format, ap); +} + +int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = ossl_prov_bio_vprintf(bio, format, ap); + va_end(ap); + + return ret; +} + +#ifndef FIPS_MODULE +/* No direct BIO support in the FIPS module */ + +static int bio_core_read_ex(BIO *bio, char *data, size_t data_len, + size_t *bytes_read) +{ + return ossl_prov_bio_read_ex(BIO_get_data(bio), data, data_len, bytes_read); +} + +static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len, + size_t *written) +{ + return ossl_prov_bio_write_ex(BIO_get_data(bio), data, data_len, written); +} + +static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + return ossl_prov_bio_ctrl(BIO_get_data(bio), cmd, num, ptr); +} + +static int bio_core_gets(BIO *bio, char *buf, int size) +{ + return ossl_prov_bio_gets(BIO_get_data(bio), buf, size); +} + +static int bio_core_puts(BIO *bio, const char *str) +{ + return ossl_prov_bio_puts(BIO_get_data(bio), str); +} + +static int bio_core_new(BIO *bio) +{ + BIO_set_init(bio, 1); + + return 1; +} + +BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(UADK_PROV_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + + return ctx->corebiometh; +} + +static int bio_core_free(BIO *bio) +{ + BIO_set_init(bio, 0); + ossl_prov_bio_free(BIO_get_data(bio)); + + return 1; +} + +BIO_METHOD *ossl_bio_prov_init_bio_method(void) +{ + BIO_METHOD *corebiometh = NULL; + + corebiometh = BIO_meth_new(BIO_TYPE_CORE_TO_PROV, "BIO to Core filter"); + if (corebiometh == NULL + || !BIO_meth_set_write_ex(corebiometh, bio_core_write_ex) + || !BIO_meth_set_read_ex(corebiometh, bio_core_read_ex) + || !BIO_meth_set_puts(corebiometh, bio_core_puts) + || !BIO_meth_set_gets(corebiometh, bio_core_gets) + || !BIO_meth_set_ctrl(corebiometh, bio_core_ctrl) + || !BIO_meth_set_create(corebiometh, bio_core_new) + || !BIO_meth_set_destroy(corebiometh, bio_core_free)) { + BIO_meth_free(corebiometh); + return NULL; + } + + return corebiometh; +} + +BIO *ossl_bio_new_from_core_bio(UADK_PROV_CTX *provctx, OSSL_CORE_BIO *corebio) +{ + BIO_METHOD *corebiometh = ossl_prov_ctx_get0_core_bio_method(provctx); + BIO *outbio; + + if (corebiometh == NULL) + return NULL; + + outbio = BIO_new(corebiometh); + if (outbio == NULL) + return NULL; + + if (!ossl_prov_bio_up_ref(corebio)) { + BIO_free(outbio); + return NULL; + } + + BIO_set_data(outbio, corebio); + + return outbio; +} +#endif diff --git a/src/uadk_prov_bio.h b/src/uadk_prov_bio.h new file mode 100644 index 0000000..2b0d044 --- /dev/null +++ b/src/uadk_prov_bio.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright 2019-2021 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 <stdarg.h> +#include <openssl/bio.h> +#include <openssl/core.h> +#include "uadk_prov.h" + +int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns); + +OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode); +OSSL_CORE_BIO *ossl_prov_bio_new_membuf(const char *filename, int len); +int ossl_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len, + size_t *bytes_read); +int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len, + size_t *written); +int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size); +int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str); +int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr); +int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio); +int ossl_prov_bio_free(OSSL_CORE_BIO *bio); +int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap); +int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...); + +BIO_METHOD *ossl_bio_prov_init_bio_method(void); +BIO *ossl_bio_new_from_core_bio(UADK_PROV_CTX *provctx, OSSL_CORE_BIO *corebio); +BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(UADK_PROV_CTX *ctx); diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index 4a81620..f521160 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -19,6 +19,7 @@ #include <stdio.h> #include <string.h>
+#include <openssl/bio.h> #include <openssl/core_dispatch.h> #include <openssl/core_names.h> #include <openssl/crypto.h> @@ -27,10 +28,16 @@
#include "uadk_async.h" #include "uadk_prov.h" +#include "uadk_prov_bio.h"
static const char UADK_DEFAULT_PROPERTIES[] = "provider=uadk_provider"; static OSSL_PROVIDER *prov;
+/* Functions provided by the core */ +static OSSL_FUNC_core_gettable_params_fn *c_gettable_params; +static OSSL_FUNC_core_get_params_fn *c_get_params; +static OSSL_FUNC_core_get_libctx_fn *c_get_libctx; + /* Functions provided by the core */ static OSSL_FUNC_core_get_params_fn *c_get_params; static OSSL_FUNC_core_get_libctx_fn *c_get_libctx; @@ -199,38 +206,75 @@ static void provider_init_child_at_fork_handler(void) fprintf(stderr, "async_module_init fail!\n"); }
-int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, - const OSSL_DISPATCH *oin, - const OSSL_DISPATCH **out, - void **provctx) +static int uadk_prov_ctx_set_core_bio_method(struct uadk_prov_ctx *ctx) { - struct uadk_prov_ctx *ctx; - int ret; + UADK_BIO_METHOD *core_bio;
- for (; oin->function_id != 0; oin++) { - switch (oin->function_id) { + core_bio = ossl_bio_prov_init_bio_method(); + if (core_bio == NULL) { + fprintf(stderr, "failed to set bio from dispatch\n"); + return 0; + } + + ctx->corebiometh = core_bio; + + return 1; +} + +static void ossl_prov_core_from_dispatch(const OSSL_DISPATCH *fns) +{ + for (fns; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_CORE_GETTABLE_PARAMS: + c_gettable_params = OSSL_FUNC_core_gettable_params(fns); + break; case OSSL_FUNC_CORE_GET_PARAMS: - c_get_params = OSSL_FUNC_core_get_params(oin); + c_get_params = OSSL_FUNC_core_get_params(fns); break; case OSSL_FUNC_CORE_GET_LIBCTX: - c_get_libctx = OSSL_FUNC_core_get_libctx(oin); + c_get_libctx = OSSL_FUNC_core_get_libctx(fns); break; default: - /* Just ignore anything we don't understand */ + /* Just ignore anything we don't understand */ break; } } +} + +int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *oin, + const OSSL_DISPATCH **out, + void **provctx) +{ + struct uadk_prov_ctx *ctx; + int ret; + + if (oin == NULL) { + fprintf(stderr, "failed to get dispatch in\n"); + return 0; + } + + (void)ossl_prov_bio_from_dispatch(oin); + ossl_prov_core_from_dispatch(oin);
/* get parameters from uadk_provider.cnf */ if (!uadk_get_params_from_core(handle)) return 0;
ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) + if (ctx == NULL) { + fprintf(stderr, "failed to alloc ctx\n"); return 0; + }
+ /* Set handle from core to get core functions */ ctx->handle = handle; ctx->libctx = (OSSL_LIB_CTX *)c_get_libctx(handle); + + ret = uadk_prov_ctx_set_core_bio_method(ctx); + if (!ret) + return 0; + ret = async_module_init(); if (!ret) fprintf(stderr, "async_module_init fail!\n"); @@ -238,5 +282,6 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
*provctx = (void *)ctx; *out = uadk_dispatch_table; + return 1; }