You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ji...@apache.org on 2026/01/19 14:51:21 UTC
(nuttx-apps) 01/05: openssl_wrapper_mbedtls: support bio interfaces in openssl
This is an automated email from the ASF dual-hosted git repository.
jiuzhudong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit 33d5062ba68c7405035608941a31e3b76ad3db3e
Author: makejian <ma...@xiaomi.com>
AuthorDate: Wed Jun 4 11:12:20 2025 +0800
openssl_wrapper_mbedtls: support bio interfaces in openssl
VELAPLATFO-62586
Change-Id: I5d7675c05dc3a52c1cb15a6132b969a19f848248
Signed-off-by: makejian <ma...@xiaomi.com>
(cherry picked from commit 409c86a062a816b56a3a48b1111102d12f24a48f)
---
.../openssl_mbedtls_wrapper/include/openssl/bio.h | 72 ++++++-
.../include/openssl/types.h | 4 +-
crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c | 147 +++++++++++++
crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c | 151 +++++++++++++
crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c | 236 +++++++++++++++++++++
5 files changed, 608 insertions(+), 2 deletions(-)
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/bio.h b/crypto/openssl_mbedtls_wrapper/include/openssl/bio.h
index be8acf198..7bfab1eb9 100644
--- a/crypto/openssl_mbedtls_wrapper/include/openssl/bio.h
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/bio.h
@@ -27,16 +27,86 @@
****************************************************************************/
#include <openssl/base.h>
+#include <openssl/types.h>
/****************************************************************************
- * Public Function Prototypes
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* There are the classes of BIOs */
+
+#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */
+#define BIO_TYPE_FILTER 0x0200
+#define BIO_TYPE_SOURCE_SINK 0x0400
+
+#define BIO_FLAGS_BASE64_NO_NL 0x100
+
+/* This is used with memory BIOs: BIO_FLAGS_MEM_RDONLY
+ * means we shouldn't free up or change the data in any way;
+ * BIO_FLAGS_NONCLEAR_RST means we shouldn't clear data on reset.
+ */
+
+#define BIO_FLAGS_MEM_RDONLY 0x200
+#define BIO_FLAGS_NONCLEAR_RST 0x400
+#define BIO_FLAGS_IN_EOF 0x800
+
+#define BIO_TYPE_NONE 0
+#define BIO_TYPE_MEM (1 | BIO_TYPE_SOURCE_SINK)
+#define BIO_TYPE_FILE (2 | BIO_TYPE_SOURCE_SINK)
+#define BIO_TYPE_BASE64 (11 | BIO_TYPE_FILTER)
+
+/****************************************************************************
+ * Public Types
****************************************************************************/
+struct bio_method_st
+{
+ int type;
+ char *name;
+ int (*bwrite_old) (BIO *, const char *, int);
+ int (*bread_old) (BIO *, char *, int);
+ int (*create) (BIO *);
+ int (*destroy) (BIO *);
+};
+
+struct bio_st
+{
+ const BIO_METHOD *method;
+ int flags; /* extra storage */
+ void *ptr;
+ struct bio_st *next_bio; /* used by filter BIOs */
+ struct bio_st *prev_bio; /* used by filter BIOs */
+};
+
#ifdef __cplusplus
extern "C"
{
#endif
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+const BIO_METHOD *BIO_f_base64(void);
+
+const BIO_METHOD *BIO_s_mem(void);
+
+BIO *BIO_new(const BIO_METHOD *method);
+
+BIO *BIO_push(BIO *b, BIO *bio);
+
+void BIO_set_flags(BIO *b, int flags);
+
+int BIO_write(BIO *b, const void *data, int dlen);
+
+int BIO_read(BIO *b, void *data, int dlen);
+
+void BIO_free_all(BIO *bio);
+
+BIO *BIO_next(BIO *b);
+
+int BIO_flush(BIO *b);
+
#ifdef __cplusplus
}
#endif
diff --git a/crypto/openssl_mbedtls_wrapper/include/openssl/types.h b/crypto/openssl_mbedtls_wrapper/include/openssl/types.h
index 679fb94c5..c03078645 100644
--- a/crypto/openssl_mbedtls_wrapper/include/openssl/types.h
+++ b/crypto/openssl_mbedtls_wrapper/include/openssl/types.h
@@ -29,10 +29,12 @@ typedef void SSL_CIPHER;
typedef void X509_STORE;
typedef void RSA;
-typedef void BIO;
typedef int (*OPENSSL_sk_compfunc)(const void *, const void *);
+typedef struct bio_buf_mem_st BIO_BUF_MEM;
+typedef struct bio_method_st BIO_METHOD;
+typedef struct bio_st BIO;
typedef struct stack_st OPENSSL_STACK;
typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_method_func_st SSL_METHOD_FUNC;
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c b/crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c
new file mode 100644
index 000000000..a13d4f26c
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c
@@ -0,0 +1,147 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/bio_b64.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <sys/param.h>
+
+#include <mbedtls/base64.h>
+#include <openssl/bio.h>
+#include <openssl/types.h>
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+#define BIO_B64_BUFSIZE ((BIO_B64_ENC_LEN / 3) * 4 + 1)
+#define BIO_B64_ENC_LEN 192
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int b64_write(BIO *h, const char *buf, int num);
+static int b64_read(BIO *h, char *buf, int size);
+static int b64_new(BIO *h);
+static int b64_free(BIO *data);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const BIO_METHOD g_methods_b64 =
+{
+ BIO_TYPE_BASE64,
+ "base64 encoding",
+ b64_write,
+ b64_read,
+ b64_new,
+ b64_free,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int b64_write(BIO *b, const char *in, int inl)
+{
+ BIO *next;
+ int len;
+ int offset = 0;
+ int ret = 0;
+ size_t n;
+ unsigned char out[BIO_B64_BUFSIZE];
+
+ next = BIO_next(b);
+ if (next == NULL)
+ {
+ return 0;
+ }
+
+ while (inl > 0)
+ {
+ len = MIN(inl, BIO_B64_ENC_LEN);
+ ret = mbedtls_base64_encode(out, BIO_B64_BUFSIZE, &n,
+ (const unsigned char *)in + offset, len);
+ if (ret < 0)
+ {
+ break;
+ }
+
+ ret = BIO_write(next, out, n);
+ inl -= len;
+ offset += len;
+ }
+
+ return ret;
+}
+
+static int b64_read(BIO *b, char *out, int outl)
+{
+ BIO *next;
+ int ret;
+ size_t n;
+
+ if (out == NULL)
+ {
+ return 0;
+ }
+
+ next = BIO_next(b);
+ if (next == NULL)
+ {
+ return 0;
+ }
+
+ ret = BIO_read(next, out, outl);
+ if (ret > 0)
+ {
+ ret = mbedtls_base64_decode((unsigned char *)out, outl, &n,
+ (const unsigned char *)out, ret);
+ if (ret == 0)
+ {
+ ret = n;
+ }
+ }
+
+ return ret;
+}
+
+static int b64_new(BIO *bi)
+{
+ return 1;
+}
+
+static int b64_free(BIO *a)
+{
+ return 1;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+const BIO_METHOD *BIO_f_base64(void)
+{
+ return &g_methods_b64;
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c b/crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c
new file mode 100644
index 000000000..36d08403a
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c
@@ -0,0 +1,151 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/bio_lib.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdio.h>
+
+#include <openssl/bio.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+BIO *BIO_new(const BIO_METHOD *method)
+{
+ BIO *bio = zalloc(sizeof(*bio));
+
+ if (bio == NULL)
+ {
+ return NULL;
+ }
+
+ bio->method = method;
+
+ if (method->create != NULL && !method->create(bio))
+ {
+ free(bio);
+ return NULL;
+ }
+
+ return bio;
+}
+
+BIO *BIO_push(BIO *b, BIO *bio)
+{
+ BIO *lb;
+
+ if (b == NULL)
+ {
+ return bio;
+ }
+ else if (bio == NULL)
+ {
+ return b;
+ }
+
+ lb = b;
+ while (lb->next_bio != NULL)
+ {
+ lb = lb->next_bio;
+ }
+
+ lb->next_bio = bio;
+ bio->prev_bio = lb;
+ return b;
+}
+
+void BIO_set_flags(BIO *b, int flags)
+{
+ b->flags |= flags;
+}
+
+int BIO_write(BIO *b, const void *data, int dlen)
+{
+ if (b == NULL || dlen <= 0)
+ {
+ return 0;
+ }
+
+ if (b->method == NULL || b->method->bwrite_old == NULL)
+ {
+ return -2;
+ }
+
+ return b->method->bwrite_old(b, data, dlen);
+}
+
+int BIO_read(BIO *b, void *data, int dlen)
+{
+ if (b == NULL || dlen <= 0)
+ {
+ return 0;
+ }
+
+ if (b->method == NULL || b->method->bread_old == NULL)
+ {
+ return -2;
+ }
+
+ return b->method->bread_old(b, data, dlen);
+}
+
+int BIO_free(BIO *a)
+{
+ if (a == NULL)
+ {
+ return 0;
+ }
+
+ if (a->method != NULL && a->method->destroy != NULL)
+ {
+ a->method->destroy(a);
+ }
+
+ free(a);
+ return 1;
+}
+
+void BIO_free_all(BIO *bio)
+{
+ while (bio != NULL)
+ {
+ BIO *b = bio;
+ bio = bio->next_bio;
+ BIO_free(b);
+ }
+}
+
+BIO *BIO_next(BIO *b)
+{
+ if (b == NULL)
+ {
+ return NULL;
+ }
+
+ return b->next_bio;
+}
+
+int BIO_flush(BIO *b)
+{
+ return 1;
+}
diff --git a/crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c b/crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c
new file mode 100644
index 000000000..40f884135
--- /dev/null
+++ b/crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c
@@ -0,0 +1,236 @@
+/****************************************************************************
+ * apps/crypto/openssl_mbedtls_wrapper/mbedtls/bss_mem.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+
+#include <openssl/bio.h>
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
+ * function is applied in several functions in this file and this limit
+ * ensures that the result fits in an int.
+ */
+
+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int mem_write(BIO *h, const char *buf, int num);
+static int mem_read(BIO *h, char *buf, int size);
+static int mem_new(BIO *h);
+static int mem_free(BIO *data);
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct bio_buf_mem_st
+{
+ unsigned long flags;
+ char *data;
+ size_t length; /* current number of bytes */
+ size_t max; /* size of buffer */
+ size_t offset; /* has been read */
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const BIO_METHOD g_mem_method =
+{
+ BIO_TYPE_MEM,
+ "memory buffer",
+ mem_write,
+ mem_read,
+ mem_new,
+ mem_free,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int mem_buf_sync(BIO *b)
+{
+ if (b != NULL && b->ptr != NULL)
+ {
+ BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+
+ if (bbm->offset)
+ {
+ bbm->length = bbm->length - bbm->offset;
+ memmove(bbm->data, bbm->data + bbm->offset, bbm->length);
+ bbm->offset = 0;
+ }
+ }
+
+ return 0;
+}
+
+static size_t BUF_MEM_grow_clean(BIO_BUF_MEM *bbm, size_t len)
+{
+ char *ret;
+ size_t n;
+
+ if (bbm->length >= len)
+ {
+ if (bbm->data != NULL)
+ {
+ memset(&bbm->data[len], 0, bbm->length - len);
+ }
+
+ bbm->length = len;
+ return len;
+ }
+
+ if (bbm->max >= len)
+ {
+ memset(&bbm->data[bbm->length], 0, len - bbm->length);
+ bbm->length = len;
+ return len;
+ }
+
+ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+
+ if (len > LIMIT_BEFORE_EXPANSION)
+ {
+ return 0;
+ }
+
+ n = MAX((len + 3) / 3 * 4, bbm->max);
+ ret = realloc(bbm->data, n);
+ if (ret == NULL)
+ {
+ return 0;
+ }
+
+ bbm->data = ret;
+ bbm->max = n;
+ bbm->length = len;
+ return len;
+}
+
+static int mem_write(BIO *b, const char *in, int inl)
+{
+ BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+ int blen;
+
+ if (b->flags & BIO_FLAGS_MEM_RDONLY)
+ {
+ return -1;
+ }
+
+ if (inl <= 0)
+ {
+ return 0;
+ }
+ else if (in == NULL)
+ {
+ return -1;
+ }
+
+ blen = bbm->length - bbm->offset;
+ mem_buf_sync(b);
+ if (BUF_MEM_grow_clean(bbm, blen + inl) == 0)
+ {
+ return -1;
+ }
+
+ memcpy(bbm->data + blen, in, inl);
+ return inl;
+}
+
+static int mem_read(BIO *b, char *out, int outl)
+{
+ BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+
+ if (outl <= 0)
+ {
+ return 0;
+ }
+
+ if (out == NULL)
+ {
+ return -1;
+ }
+
+ if (outl > bbm->length - bbm->offset)
+ {
+ outl = bbm->length - bbm->offset;
+ }
+
+ memcpy(out, bbm->data + bbm->offset, outl);
+ bbm->offset += outl;
+ return outl;
+}
+
+static int mem_new(BIO *bi)
+{
+ BIO_BUF_MEM *bbm = zalloc(sizeof(*bbm));
+
+ if (bbm == NULL)
+ {
+ return 0;
+ }
+
+ bi->ptr = bbm;
+ return 1;
+}
+
+static int mem_free(BIO *a)
+{
+ BIO_BUF_MEM *bbm;
+
+ if (a == NULL)
+ {
+ return 0;
+ }
+
+ bbm = (BIO_BUF_MEM *)a->ptr;
+ if (bbm->data)
+ {
+ free(bbm->data);
+ }
+
+ free(bbm);
+ return 1;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+const BIO_METHOD *BIO_s_mem(void)
+{
+ return &g_mem_method;
+}