Remove non-namespaced symbols for ctor/dtor of BIO.

Bug: 42220000
Change-Id: I172a9e4f963b7478326b5273c52801f56a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/87707
Auto-Submit: Rudolf Polzer <rpolzer@google.com>
Reviewed-by: Xiangfei Ding <xfding@google.com>
Commit-Queue: Rudolf Polzer <rpolzer@google.com>
diff --git a/crypto/bio/bio.cc b/crypto/bio/bio.cc
index bc6ef67..7f6a052 100644
--- a/crypto/bio/bio.cc
+++ b/crypto/bio/bio.cc
@@ -34,7 +34,7 @@
     CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
 
 BIO *BIO_new(const BIO_METHOD *method) {
-  BIO *ret = NewZeroed<BIO>();
+  Bio *ret = NewZeroed<Bio>();
   if (ret == nullptr) {
     return nullptr;
   }
@@ -53,27 +53,31 @@
 }
 
 int BIO_free(BIO *bio) {
-  BIO *next_bio;
+  auto *impl = FromOpaque(bio);
 
-  for (; bio != nullptr; bio = next_bio) {
-    if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) {
+  Bio *next_bio;
+
+  for (; impl != nullptr; impl = next_bio) {
+    if (!CRYPTO_refcount_dec_and_test_zero(&impl->references)) {
       return 0;
     }
 
-    next_bio = BIO_pop(bio);
+    next_bio = FromOpaque(BIO_pop(impl));
 
-    if (bio->method != nullptr && bio->method->destroy != nullptr) {
-      bio->method->destroy(bio);
+    if (impl->method != nullptr && impl->method->destroy != nullptr) {
+      impl->method->destroy(impl);
     }
 
-    CRYPTO_free_ex_data(&g_ex_data_class, &bio->ex_data);
-    Delete(bio);
+    CRYPTO_free_ex_data(&g_ex_data_class, &impl->ex_data);
+    Delete(impl);
   }
   return 1;
 }
 
 int BIO_up_ref(BIO *bio) {
-  CRYPTO_refcount_inc(&bio->references);
+  auto *impl = FromOpaque(bio);
+
+  CRYPTO_refcount_inc(&impl->references);
   return 1;
 }
 
@@ -82,61 +86,67 @@
 void BIO_free_all(BIO *bio) { BIO_free(bio); }
 
 int BIO_read(BIO *bio, void *buf, int len) {
-  if (bio == nullptr || bio->method == nullptr ||
-      bio->method->bread == nullptr) {
+  auto *impl = FromOpaque(bio);
+
+  if (impl == nullptr || impl->method == nullptr ||
+      impl->method->bread == nullptr) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return -2;
   }
-  if (!bio->init) {
+  if (!impl->init) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
     return -2;
   }
   if (len <= 0) {
     return 0;
   }
-  int ret = bio->method->bread(bio, reinterpret_cast<char *>(buf), len);
+  int ret = impl->method->bread(bio, reinterpret_cast<char *>(buf), len);
   if (ret > 0) {
-    bio->num_read += ret;
+    impl->num_read += ret;
   }
   return ret;
 }
 
 int BIO_gets(BIO *bio, char *buf, int len) {
-  if (bio == nullptr || bio->method == nullptr ||
-      bio->method->bgets == nullptr) {
+  auto *impl = FromOpaque(bio);
+
+  if (bio == nullptr || impl->method == nullptr ||
+      impl->method->bgets == nullptr) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return -2;
   }
-  if (!bio->init) {
+  if (!impl->init) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
     return -2;
   }
   if (len <= 0) {
     return 0;
   }
-  int ret = bio->method->bgets(bio, buf, len);
+  int ret = impl->method->bgets(bio, buf, len);
   if (ret > 0) {
-    bio->num_read += ret;
+    impl->num_read += ret;
   }
   return ret;
 }
 
 int BIO_write(BIO *bio, const void *in, int inl) {
-  if (bio == nullptr || bio->method == nullptr ||
-      bio->method->bwrite == nullptr) {
+  auto *impl = FromOpaque(bio);
+
+  if (bio == nullptr || impl->method == nullptr ||
+      impl->method->bwrite == nullptr) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return -2;
   }
-  if (!bio->init) {
+  if (!impl->init) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
     return -2;
   }
   if (inl <= 0) {
     return 0;
   }
-  int ret = bio->method->bwrite(bio, reinterpret_cast<const char *>(in), inl);
+  int ret = impl->method->bwrite(bio, reinterpret_cast<const char *>(in), inl);
   if (ret > 0) {
-    bio->num_write += ret;
+    impl->num_write += ret;
   }
   return ret;
 }
@@ -169,16 +179,18 @@
 }
 
 long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
+  auto *impl = FromOpaque(bio);
+
   if (bio == nullptr) {
     return 0;
   }
 
-  if (bio->method == nullptr || bio->method->ctrl == nullptr) {
+  if (impl->method == nullptr || impl->method->ctrl == nullptr) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return -2;
   }
 
-  return bio->method->ctrl(bio, cmd, larg, parg);
+  return impl->method->ctrl(bio, cmd, larg, parg);
 }
 
 char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) {
@@ -203,9 +215,17 @@
 
 int BIO_eof(BIO *bio) { return (int)BIO_ctrl(bio, BIO_CTRL_EOF, 0, nullptr); }
 
-void BIO_set_flags(BIO *bio, int flags) { bio->flags |= flags; }
+void BIO_set_flags(BIO *bio, int flags) {
+  auto *impl = FromOpaque(bio);
 
-int BIO_test_flags(const BIO *bio, int flags) { return bio->flags & flags; }
+  impl->flags |= flags;
+}
+
+int BIO_test_flags(const BIO *bio, int flags) {
+  auto *impl = FromOpaque(bio);
+
+  return impl->flags & flags;
+}
 
 int BIO_should_read(const BIO *bio) {
   return BIO_test_flags(bio, BIO_FLAGS_READ);
@@ -223,48 +243,78 @@
   return BIO_test_flags(bio, BIO_FLAGS_IO_SPECIAL);
 }
 
-int BIO_get_retry_reason(const BIO *bio) { return bio->retry_reason; }
+int BIO_get_retry_reason(const BIO *bio) {
+  auto *impl = FromOpaque(bio);
 
-void BIO_set_retry_reason(BIO *bio, int reason) { bio->retry_reason = reason; }
+  return impl->retry_reason;
+}
 
-void BIO_clear_flags(BIO *bio, int flags) { bio->flags &= ~flags; }
+void BIO_set_retry_reason(BIO *bio, int reason) {
+  auto *impl = FromOpaque(bio);
+
+  impl->retry_reason = reason;
+}
+
+void BIO_clear_flags(BIO *bio, int flags) {
+  auto *impl = FromOpaque(bio);
+
+  impl->flags &= ~flags;
+}
 
 void BIO_set_retry_read(BIO *bio) {
-  bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY;
+  auto *impl = FromOpaque(bio);
+
+  impl->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY;
 }
 
 void BIO_set_retry_write(BIO *bio) {
-  bio->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY;
+  auto *impl = FromOpaque(bio);
+
+  impl->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY;
 }
 
 static const int kRetryFlags = BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY;
 
-int BIO_get_retry_flags(BIO *bio) { return bio->flags & kRetryFlags; }
+int BIO_get_retry_flags(BIO *bio) {
+  auto *impl = FromOpaque(bio);
 
-void BIO_clear_retry_flags(BIO *bio) {
-  bio->flags &= ~kRetryFlags;
-  bio->retry_reason = 0;
+  return impl->flags & kRetryFlags;
 }
 
-int BIO_method_type(const BIO *bio) { return bio->method->type; }
+void BIO_clear_retry_flags(BIO *bio) {
+  auto *impl = FromOpaque(bio);
+
+  impl->flags &= ~kRetryFlags;
+  impl->retry_reason = 0;
+}
+
+int BIO_method_type(const BIO *bio) {
+  auto *impl = FromOpaque(bio);
+
+  return impl->method->type;
+}
 
 void BIO_copy_next_retry(BIO *bio) {
+  auto *impl = FromOpaque(bio);
+
   BIO_clear_retry_flags(bio);
-  BIO_set_flags(bio, BIO_get_retry_flags(bio->next_bio));
-  bio->retry_reason = bio->next_bio->retry_reason;
+  BIO_set_flags(bio, BIO_get_retry_flags(impl->next_bio));
+  impl->retry_reason = impl->next_bio->retry_reason;
 }
 
 long BIO_callback_ctrl(BIO *bio, int cmd, BIO_info_cb *fp) {
+  auto *impl = FromOpaque(bio);
+
   if (bio == nullptr) {
     return 0;
   }
 
-  if (bio->method == nullptr || bio->method->callback_ctrl == nullptr) {
+  if (impl->method == nullptr || impl->method->callback_ctrl == nullptr) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
     return 0;
   }
 
-  return bio->method->callback_ctrl(bio, cmd, fp);
+  return impl->method->callback_ctrl(bio, cmd, fp);
 }
 
 size_t BIO_pending(const BIO *bio) {
@@ -294,48 +344,60 @@
 }
 
 OPENSSL_EXPORT uint64_t BIO_number_read(const BIO *bio) {
-  return bio->num_read;
+  auto *impl = FromOpaque(bio);
+
+  return impl->num_read;
 }
 
 OPENSSL_EXPORT uint64_t BIO_number_written(const BIO *bio) {
-  return bio->num_write;
+  auto *impl = FromOpaque(bio);
+
+  return impl->num_write;
 }
 
 BIO *BIO_push(BIO *bio, BIO *appended_bio) {
-  BIO *last_bio;
+  auto *impl = FromOpaque(bio);
+
+  Bio *last_bio;
 
   if (bio == nullptr) {
     return bio;
   }
 
-  last_bio = bio;
+  last_bio = impl;
   while (last_bio->next_bio != nullptr) {
     last_bio = last_bio->next_bio;
   }
 
-  last_bio->next_bio = appended_bio;
+  last_bio->next_bio = FromOpaque(appended_bio);
   return bio;
 }
 
 BIO *BIO_pop(BIO *bio) {
+  auto *impl = FromOpaque(bio);
+
   BIO *ret;
 
   if (bio == nullptr) {
     return nullptr;
   }
-  ret = bio->next_bio;
-  bio->next_bio = nullptr;
+  ret = impl->next_bio;
+  impl->next_bio = nullptr;
   return ret;
 }
 
 BIO *BIO_next(BIO *bio) {
+  auto *impl = FromOpaque(bio);
+
   if (!bio) {
     return nullptr;
   }
-  return bio->next_bio;
+  return impl->next_bio;
 }
 
 BIO *BIO_find_type(BIO *bio, int type) {
+  auto *impl = FromOpaque(bio);
+
   int method_type, mask;
 
   if (!bio) {
@@ -344,8 +406,8 @@
   mask = type & 0xff;
 
   do {
-    if (bio->method != nullptr) {
-      method_type = bio->method->type;
+    if (impl->method != nullptr) {
+      method_type = impl->method->type;
 
       if (!mask) {
         if (method_type & type) {
@@ -355,7 +417,7 @@
         return bio;
       }
     }
-    bio = bio->next_bio;
+    bio = impl->next_bio;
   } while (bio != nullptr);
 
   return nullptr;
@@ -388,7 +450,7 @@
 //
 // The function will fail if the size of the output would equal or exceed
 // |max_len|.
-static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len,
+static int bio_read_all(Bio *bio, uint8_t **out, size_t *out_len,
                         const uint8_t *prefix, size_t prefix_len,
                         size_t max_len) {
   static const size_t kChunkSize = 4096;
@@ -447,7 +509,7 @@
 // read fails before |len| bytes are read. On failure, it additionally sets
 // |*out_eof_on_first_read| to whether the error was due to |bio| returning zero
 // on the first read. |out_eof_on_first_read| may be NULL to discard the value.
-static int bio_read_full(BIO *bio, uint8_t *out, int *out_eof_on_first_read,
+static int bio_read_full(Bio *bio, uint8_t *out, int *out_eof_on_first_read,
                          size_t len) {
   int first_read = 1;
   while (len > 0) {
@@ -479,7 +541,8 @@
 
   static const size_t kInitialHeaderLen = 2;
   int eof_on_first_read;
-  if (!bio_read_full(bio, header, &eof_on_first_read, kInitialHeaderLen)) {
+  auto *impl = FromOpaque(bio);
+  if (!bio_read_full(impl, header, &eof_on_first_read, kInitialHeaderLen)) {
     if (eof_on_first_read) {
       // Historically, OpenSSL returned |ASN1_R_HEADER_TOO_LONG| when
       // |d2i_*_bio| could not read anything. CPython conditions on this to
@@ -510,7 +573,7 @@
 
     if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) {
       // indefinite length.
-      if (!bio_read_all(bio, out, out_len, header, kInitialHeaderLen,
+      if (!bio_read_all(impl, out, out_len, header, kInitialHeaderLen,
                         max_len)) {
         OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
         return 0;
@@ -523,7 +586,7 @@
       return 0;
     }
 
-    if (!bio_read_full(bio, header + kInitialHeaderLen, nullptr, num_bytes)) {
+    if (!bio_read_full(impl, header + kInitialHeaderLen, nullptr, num_bytes)) {
       OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
       return 0;
     }
@@ -562,7 +625,7 @@
     return 0;
   }
   OPENSSL_memcpy(*out, header, header_len);
-  if (!bio_read_full(bio, (*out) + header_len, nullptr, len - header_len)) {
+  if (!bio_read_full(impl, (*out) + header_len, nullptr, len - header_len)) {
     OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
     OPENSSL_free(*out);
     return 0;
@@ -572,7 +635,9 @@
 }
 
 void BIO_set_retry_special(BIO *bio) {
-  bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL;
+  auto *impl = FromOpaque(bio);
+
+  impl->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL;
 }
 
 int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; }
@@ -641,17 +706,41 @@
   return 1;
 }
 
-void BIO_set_data(BIO *bio, void *ptr) { bio->ptr = ptr; }
+void BIO_set_data(BIO *bio, void *ptr) {
+  auto *impl = FromOpaque(bio);
 
-void *BIO_get_data(BIO *bio) { return bio->ptr; }
+  impl->ptr = ptr;
+}
 
-void BIO_set_init(BIO *bio, int init) { bio->init = init; }
+void *BIO_get_data(BIO *bio) {
+  auto *impl = FromOpaque(bio);
 
-int BIO_get_init(BIO *bio) { return bio->init; }
+  return impl->ptr;
+}
 
-void BIO_set_shutdown(BIO *bio, int shutdown) { bio->shutdown = shutdown; }
+void BIO_set_init(BIO *bio, int init) {
+  auto *impl = FromOpaque(bio);
 
-int BIO_get_shutdown(BIO *bio) { return bio->shutdown; }
+  impl->init = init;
+}
+
+int BIO_get_init(BIO *bio) {
+  auto *impl = FromOpaque(bio);
+
+  return impl->init;
+}
+
+void BIO_set_shutdown(BIO *bio, int shutdown) {
+  auto *impl = FromOpaque(bio);
+
+  impl->shutdown = shutdown;
+}
+
+int BIO_get_shutdown(BIO *bio) {
+  auto *impl = FromOpaque(bio);
+
+  return impl->shutdown;
+}
 
 int BIO_meth_set_puts(BIO_METHOD *method, int (*puts)(BIO *, const char *)) {
   // Ignore the parameter. We implement |BIO_puts| using |BIO_write|.
@@ -666,9 +755,13 @@
 }
 
 int BIO_set_ex_data(BIO *bio, int idx, void *data) {
-  return CRYPTO_set_ex_data(&bio->ex_data, idx, data);
+  auto *impl = FromOpaque(bio);
+
+  return CRYPTO_set_ex_data(&impl->ex_data, idx, data);
 }
 
 void *BIO_get_ex_data(const BIO *bio, int idx) {
-  return CRYPTO_get_ex_data(&bio->ex_data, idx);
+  auto *impl = FromOpaque(bio);
+
+  return CRYPTO_get_ex_data(&impl->ex_data, idx);
 }
diff --git a/crypto/bio/bio_mem.cc b/crypto/bio/bio_mem.cc
index 3be73ab..479b9ce 100644
--- a/crypto/bio/bio_mem.cc
+++ b/crypto/bio/bio_mem.cc
@@ -42,18 +42,18 @@
     return nullptr;
   }
 
-  b = (BUF_MEM *)ret->ptr;
+  b = (BUF_MEM *)BIO_get_data(ret);
   // BIO_FLAGS_MEM_RDONLY ensures |b->data| is not written to.
   b->data = reinterpret_cast<char *>(const_cast<void *>(buf));
   b->length = size;
   b->max = size;
 
-  ret->flags |= BIO_FLAGS_MEM_RDONLY;
+  BIO_set_flags(ret, BIO_FLAGS_MEM_RDONLY);
 
   // |num| is used to store the value that this BIO will return when it runs
   // out of data. If it's negative then the retry flags will also be set. Since
   // this is static data, retrying won't help
-  ret->num = 0;
+  FromOpaque(ret)->num = 0;
 
   return ret;
 }
@@ -68,25 +68,26 @@
 
   // |shutdown| is used to store the close flag: whether the BIO has ownership
   // of the BUF_MEM.
-  bio->shutdown = 1;
-  bio->init = 1;
-  bio->num = -1;
-  bio->ptr = (char *)b;
+  BIO_set_shutdown(bio, 1);
+  BIO_set_init(bio, 1);
+  FromOpaque(bio)->num = -1;
+  BIO_set_data(bio, (char *)b);
 
   return 1;
 }
 
 static int mem_free(BIO *bio) {
-  if (!bio->shutdown || !bio->init || bio->ptr == nullptr) {
+  if (!BIO_get_shutdown(bio) || !BIO_get_init(bio) ||
+      BIO_get_data(bio) == nullptr) {
     return 1;
   }
 
-  BUF_MEM *b = (BUF_MEM *)bio->ptr;
-  if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
+  BUF_MEM *b = (BUF_MEM *)BIO_get_data(bio);
+  if (BIO_test_flags(bio, BIO_FLAGS_MEM_RDONLY)) {
     b->data = nullptr;
   }
   BUF_MEM_free(b);
-  bio->ptr = nullptr;
+  BIO_set_data(bio, nullptr);
   return 1;
 }
 
@@ -96,7 +97,7 @@
     return 0;
   }
 
-  BUF_MEM *b = reinterpret_cast<BUF_MEM *>(bio->ptr);
+  BUF_MEM *b = reinterpret_cast<BUF_MEM *>(BIO_get_data(bio));
   int ret = outl;
   if ((size_t)ret > b->length) {
     ret = (int)b->length;
@@ -105,13 +106,13 @@
   if (ret > 0) {
     OPENSSL_memcpy(out, b->data, ret);
     b->length -= ret;
-    if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
+    if (BIO_test_flags(bio, BIO_FLAGS_MEM_RDONLY)) {
       b->data += ret;
     } else {
       OPENSSL_memmove(b->data, &b->data[ret], b->length);
     }
   } else if (b->length == 0) {
-    ret = bio->num;
+    ret = FromOpaque(bio)->num;
     if (ret != 0) {
       BIO_set_retry_read(bio);
     }
@@ -125,12 +126,12 @@
     return 0;  // Successfully write zero bytes.
   }
 
-  if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
+  if (BIO_test_flags(bio, BIO_FLAGS_MEM_RDONLY)) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO);
     return -1;
   }
 
-  BUF_MEM *b = reinterpret_cast<BUF_MEM *>(bio->ptr);
+  BUF_MEM *b = reinterpret_cast<BUF_MEM *>(BIO_get_data(bio));
   if (!BUF_MEM_append(b, in, inl)) {
     return -1;
   }
@@ -146,7 +147,7 @@
 
   // The buffer size includes space for the trailing NUL, so we can read at most
   // one fewer byte.
-  BUF_MEM *b = reinterpret_cast<BUF_MEM *>(bio->ptr);
+  BUF_MEM *b = reinterpret_cast<BUF_MEM *>(BIO_get_data(bio));
   int ret = size - 1;
   if ((size_t)ret > b->length) {
     ret = (int)b->length;
@@ -167,12 +168,12 @@
 }
 
 static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) {
-  BUF_MEM *b = static_cast<BUF_MEM *>(bio->ptr);
+  BUF_MEM *b = static_cast<BUF_MEM *>(BIO_get_data(bio));
   switch (cmd) {
     case BIO_CTRL_RESET:
       if (b->data != nullptr) {
         // For read only case reset to the start again
-        if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
+        if (BIO_test_flags(bio, BIO_FLAGS_MEM_RDONLY)) {
           b->data -= b->max - b->length;
           b->length = b->max;
         } else {
@@ -184,7 +185,7 @@
     case BIO_CTRL_EOF:
       return b->length == 0;
     case BIO_C_SET_BUF_MEM_EOF_RETURN:
-      bio->num = static_cast<int>(num);
+      FromOpaque(bio)->num = static_cast<int>(num);
       return 1;
     case BIO_CTRL_INFO:
       if (ptr != nullptr) {
@@ -196,8 +197,8 @@
       return static_cast<long>(b->length);
     case BIO_C_SET_BUF_MEM:
       mem_free(bio);
-      bio->shutdown = static_cast<int>(num);
-      bio->ptr = ptr;
+      BIO_set_shutdown(bio, static_cast<int>(num));
+      BIO_set_data(bio, ptr);
       return 1;
     case BIO_C_GET_BUF_MEM_PTR:
       if (ptr != nullptr) {
@@ -206,9 +207,9 @@
       }
       return 1;
     case BIO_CTRL_GET_CLOSE:
-      return bio->shutdown;
+      return BIO_get_shutdown(bio);
     case BIO_CTRL_SET_CLOSE:
-      bio->shutdown = static_cast<int>(num);
+      BIO_set_shutdown(bio, static_cast<int>(num));
       return 1;
     case BIO_CTRL_WPENDING:
       return 0;
@@ -233,11 +234,11 @@
 int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents,
                      size_t *out_len) {
   const BUF_MEM *b;
-  if (bio->method != &mem_method) {
+  if (FromOpaque(bio)->method != &mem_method) {
     return 0;
   }
 
-  b = (BUF_MEM *)bio->ptr;
+  b = (BUF_MEM *)BIO_get_data((BIO *)bio);
   *out_contents = (uint8_t *)b->data;
   *out_len = b->length;
   return 1;
diff --git a/crypto/bio/connect.cc b/crypto/bio/connect.cc
index c196891..6dcce49 100644
--- a/crypto/bio/connect.cc
+++ b/crypto/bio/connect.cc
@@ -59,8 +59,8 @@
   struct sockaddr_storage them;
   socklen_t them_length;
 
-  // the file descriptor is kept in bio->num in order to match the socket
-  // BIO.
+  // the file descriptor is kept in FromOpaque(bio)->num in order to match the
+  // socket BIO.
 
   // info_callback is called when the connection is initially made
   // callback(BIO,state,ret);  The callback should return 'ret', state is for
@@ -164,15 +164,15 @@
         }
 
         if (!bio_ip_and_port_to_socket_and_addr(
-                &bio->num, &c->them, &c->them_length, c->param_hostname,
-                c->param_port)) {
+                &FromOpaque(bio)->num, &c->them, &c->them_length,
+                c->param_hostname, c->param_port)) {
           OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
           ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
           goto exit_loop;
         }
 
         if (c->nbio) {
-          if (!bio_socket_nbio(bio->num, 1)) {
+          if (!bio_socket_nbio(FromOpaque(bio)->num, 1)) {
             OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO);
             ERR_add_error_data(4, "host=", c->param_hostname, ":",
                                c->param_port);
@@ -181,8 +181,8 @@
         }
 
         i = 1;
-        ret = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i,
-                         sizeof(i));
+        ret = setsockopt(FromOpaque(bio)->num, SOL_SOCKET, SO_KEEPALIVE,
+                         (char *)&i, sizeof(i));
         if (ret < 0) {
           OPENSSL_PUT_SYSTEM_ERROR();
           OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE);
@@ -191,12 +191,13 @@
         }
 
         BIO_clear_retry_flags(bio);
-        ret = connect(bio->num, (struct sockaddr *)&c->them, c->them_length);
+        ret = connect(FromOpaque(bio)->num, (struct sockaddr *)&c->them,
+                      c->them_length);
         if (ret < 0) {
           if (bio_socket_should_retry(ret)) {
             BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY));
             c->state = BIO_CONN_S_BLOCKED_CONNECT;
-            bio->retry_reason = BIO_RR_CONNECT;
+            BIO_set_retry_reason(bio, BIO_RR_CONNECT);
           } else {
             OPENSSL_PUT_SYSTEM_ERROR();
             OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR);
@@ -210,12 +211,12 @@
         break;
 
       case BIO_CONN_S_BLOCKED_CONNECT:
-        i = bio_sock_error(bio->num);
+        i = bio_sock_error(FromOpaque(bio)->num);
         if (i) {
           if (bio_socket_should_retry(ret)) {
             BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY));
             c->state = BIO_CONN_S_BLOCKED_CONNECT;
-            bio->retry_reason = BIO_RR_CONNECT;
+            BIO_set_retry_reason(bio, BIO_RR_CONNECT);
             ret = -1;
           } else {
             BIO_clear_retry_flags(bio);
@@ -275,34 +276,34 @@
 }
 
 static int conn_new(BIO *bio) {
-  bio->init = 0;
-  bio->num = -1;
-  bio->flags = 0;
-  bio->ptr = BIO_CONNECT_new();
-  return bio->ptr != nullptr;
+  BIO_set_init(bio, 0);
+  FromOpaque(bio)->num = -1;
+  FromOpaque(bio)->flags = 0;
+  BIO_set_data(bio, BIO_CONNECT_new());
+  return BIO_get_data(bio) != nullptr;
 }
 
 static void conn_close_socket(BIO *bio) {
-  BIO_CONNECT *c = (BIO_CONNECT *)bio->ptr;
+  BIO_CONNECT *c = (BIO_CONNECT *)BIO_get_data(bio);
 
-  if (bio->num == -1) {
+  if (FromOpaque(bio)->num == -1) {
     return;
   }
 
   // Only do a shutdown if things were established
   if (c->state == BIO_CONN_S_OK) {
-    shutdown(bio->num, 2);
+    shutdown(FromOpaque(bio)->num, 2);
   }
-  closesocket(bio->num);
-  bio->num = -1;
+  closesocket(FromOpaque(bio)->num);
+  FromOpaque(bio)->num = -1;
 }
 
 static int conn_free(BIO *bio) {
-  if (bio->shutdown) {
+  if (BIO_get_shutdown(bio)) {
     conn_close_socket(bio);
   }
 
-  BIO_CONNECT_free((BIO_CONNECT *)bio->ptr);
+  BIO_CONNECT_free((BIO_CONNECT *)BIO_get_data(bio));
 
   return 1;
 }
@@ -311,7 +312,7 @@
   int ret = 0;
   BIO_CONNECT *data;
 
-  data = (BIO_CONNECT *)bio->ptr;
+  data = (BIO_CONNECT *)BIO_get_data(bio);
   if (data->state != BIO_CONN_S_OK) {
     ret = conn_state(bio, data);
     if (ret <= 0) {
@@ -320,7 +321,7 @@
   }
 
   bio_clear_socket_error();
-  ret = (int)recv(bio->num, out, out_len, 0);
+  ret = (int)recv(FromOpaque(bio)->num, out, out_len, 0);
   BIO_clear_retry_flags(bio);
   if (ret <= 0) {
     if (bio_socket_should_retry(ret)) {
@@ -335,7 +336,7 @@
   int ret;
   BIO_CONNECT *data;
 
-  data = (BIO_CONNECT *)bio->ptr;
+  data = (BIO_CONNECT *)BIO_get_data(bio);
   if (data->state != BIO_CONN_S_OK) {
     ret = conn_state(bio, data);
     if (ret <= 0) {
@@ -344,7 +345,7 @@
   }
 
   bio_clear_socket_error();
-  ret = (int)send(bio->num, in, in_len, 0);
+  ret = (int)send(FromOpaque(bio)->num, in, in_len, 0);
   BIO_clear_retry_flags(bio);
   if (ret <= 0) {
     if (bio_socket_should_retry(ret)) {
@@ -356,12 +357,12 @@
 }
 
 static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
-  BIO_CONNECT *data = static_cast<BIO_CONNECT *>(bio->ptr);
+  BIO_CONNECT *data = static_cast<BIO_CONNECT *>(BIO_get_data(bio));
   switch (cmd) {
     case BIO_CTRL_RESET:
       data->state = BIO_CONN_S_BEFORE;
       conn_close_socket(bio);
-      bio->flags = 0;
+      FromOpaque(bio)->flags = 0;
       return 0;
     case BIO_C_DO_STATE_MACHINE:
       // use this one to start the connection
@@ -374,7 +375,7 @@
       if (ptr == nullptr) {
         return 0;
       }
-      bio->init = 1;
+      BIO_set_init(bio, 1);
       if (num == 0) {
         OPENSSL_free(data->param_hostname);
         data->param_hostname =
@@ -396,19 +397,19 @@
       data->nbio = static_cast<int>(num);
       return 1;
     case BIO_C_GET_FD:
-      if (bio->init) {
+      if (BIO_get_init(bio)) {
         int *out = static_cast<int *>(ptr);
         if (out != nullptr) {
-          *out = bio->num;
+          *out = FromOpaque(bio)->num;
         }
-        return bio->num;
+        return FromOpaque(bio)->num;
       } else {
         return -1;
       }
     case BIO_CTRL_GET_CLOSE:
-      return bio->shutdown;
+      return BIO_get_shutdown(bio);
     case BIO_CTRL_SET_CLOSE:
-      bio->shutdown = static_cast<int>(num);
+      BIO_set_shutdown(bio, static_cast<int>(num));
       return 1;
     case BIO_CTRL_FLUSH:
       return 1;
@@ -423,7 +424,7 @@
 }
 
 static long conn_callback_ctrl(BIO *bio, int cmd, BIO_info_cb *fp) {
-  BIO_CONNECT *data = static_cast<BIO_CONNECT *>(bio->ptr);
+  BIO_CONNECT *data = static_cast<BIO_CONNECT *>(BIO_get_data(bio));
   switch (cmd) {
     case BIO_CTRL_SET_CALLBACK:
       data->info_callback = fp;
diff --git a/crypto/bio/fd.cc b/crypto/bio/fd.cc
index 64678a1..b49acb6 100644
--- a/crypto/bio/fd.cc
+++ b/crypto/bio/fd.cc
@@ -57,16 +57,16 @@
 
 static int fd_new(BIO *bio) {
   // num is used to store the file descriptor.
-  bio->num = -1;
+  FromOpaque(bio)->num = -1;
   return 1;
 }
 
 static int fd_free(BIO *bio) {
-  if (bio->shutdown) {
-    if (bio->init) {
-      BORINGSSL_CLOSE(bio->num);
+  if (BIO_get_shutdown(bio)) {
+    if (BIO_get_init(bio)) {
+      BORINGSSL_CLOSE(FromOpaque(bio)->num);
     }
-    bio->init = 0;
+    BIO_set_init(bio, 0);
   }
   return 1;
 }
@@ -74,7 +74,7 @@
 static int fd_read(BIO *b, char *out, int outl) {
   int ret = 0;
 
-  ret = (int)BORINGSSL_READ(b->num, out, outl);
+  ret = (int)BORINGSSL_READ(FromOpaque(b)->num, out, outl);
   BIO_clear_retry_flags(b);
   if (ret <= 0) {
     if (bio_errno_should_retry(ret)) {
@@ -86,7 +86,7 @@
 }
 
 static int fd_write(BIO *b, const char *in, int inl) {
-  int ret = (int)BORINGSSL_WRITE(b->num, in, inl);
+  int ret = (int)BORINGSSL_WRITE(FromOpaque(b)->num, in, inl);
   BIO_clear_retry_flags(b);
   if (ret <= 0) {
     if (bio_errno_should_retry(ret)) {
@@ -103,36 +103,36 @@
       num = 0;
       [[fallthrough]];
     case BIO_C_FILE_SEEK:
-      if (b->init) {
-        return (long)BORINGSSL_LSEEK(b->num, num, SEEK_SET);
+      if (BIO_get_init(b)) {
+        return (long)BORINGSSL_LSEEK(FromOpaque(b)->num, num, SEEK_SET);
       }
       return 0;
     case BIO_C_FILE_TELL:
     case BIO_CTRL_INFO:
-      if (b->init) {
-        return (long)BORINGSSL_LSEEK(b->num, 0, SEEK_CUR);
+      if (BIO_get_init(b)) {
+        return (long)BORINGSSL_LSEEK(FromOpaque(b)->num, 0, SEEK_CUR);
       }
       return 0;
     case BIO_C_SET_FD:
       fd_free(b);
-      b->num = *static_cast<int *>(ptr);
-      b->shutdown = static_cast<int>(num);
-      b->init = 1;
+      FromOpaque(b)->num = *static_cast<int *>(ptr);
+      BIO_set_shutdown(b, static_cast<int>(num));
+      BIO_set_init(b, 1);
       return 1;
     case BIO_C_GET_FD:
-      if (b->init) {
+      if (BIO_get_init(b)) {
         int *out = static_cast<int *>(ptr);
         if (out != nullptr) {
-          *out = b->num;
+          *out = FromOpaque(b)->num;
         }
-        return b->num;
+        return FromOpaque(b)->num;
       } else {
         return -1;
       }
     case BIO_CTRL_GET_CLOSE:
-      return b->shutdown;
+      return BIO_get_shutdown(b);
     case BIO_CTRL_SET_CLOSE:
-      b->shutdown = static_cast<int>(num);
+      BIO_set_shutdown(b, static_cast<int>(num));
       return 1;
     case BIO_CTRL_FLUSH:
       return 1;
diff --git a/crypto/bio/file.cc b/crypto/bio/file.cc
index 902887a..0e49ccb 100644
--- a/crypto/bio/file.cc
+++ b/crypto/bio/file.cc
@@ -97,26 +97,26 @@
 }
 
 static int file_free(BIO *bio) {
-  if (!bio->shutdown) {
+  if (!BIO_get_shutdown(bio)) {
     return 1;
   }
 
-  if (bio->init && bio->ptr != nullptr) {
-    fclose(reinterpret_cast<FILE *>(bio->ptr));
-    bio->ptr = nullptr;
+  if (BIO_get_init(bio) && BIO_get_data(bio) != nullptr) {
+    fclose(reinterpret_cast<FILE *>(BIO_get_data(bio)));
+    BIO_set_data(bio, nullptr);
   }
-  bio->init = 0;
+  BIO_set_init(bio, 0);
 
   return 1;
 }
 
 static int file_read(BIO *b, char *out, int outl) {
-  if (!b->init) {
+  if (!BIO_get_init(b)) {
     return 0;
   }
 
-  size_t ret = fread(out, 1, outl, (FILE *)b->ptr);
-  if (ret == 0 && ferror((FILE *)b->ptr)) {
+  size_t ret = fread(out, 1, outl, (FILE *)BIO_get_data(b));
+  if (ret == 0 && ferror((FILE *)BIO_get_data(b))) {
     OPENSSL_PUT_SYSTEM_ERROR();
     OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
     return -1;
@@ -127,11 +127,11 @@
 }
 
 static int file_write(BIO *b, const char *in, int inl) {
-  if (!b->init) {
+  if (!BIO_get_init(b)) {
     return 0;
   }
 
-  int ret = (int)fwrite(in, inl, 1, (FILE *)b->ptr);
+  int ret = (int)fwrite(in, inl, 1, (FILE *)BIO_get_data(b));
   if (ret > 0) {
     ret = inl;
   }
@@ -139,7 +139,7 @@
 }
 
 static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
-  FILE *fp = static_cast<FILE *>(b->ptr);
+  FILE *fp = static_cast<FILE *>(BIO_get_data(b));
   switch (cmd) {
     case BIO_CTRL_RESET:
       num = 0;
@@ -164,13 +164,13 @@
         _setmode(_fileno(reinterpret_cast<FILE *>(ptr)), _O_TEXT);
       }
 #endif
-      b->shutdown = static_cast<int>(num) & BIO_CLOSE;
-      b->ptr = ptr;
-      b->init = 1;
+      BIO_set_shutdown(b, static_cast<int>(num) & BIO_CLOSE);
+      BIO_set_data(b, ptr);
+      BIO_set_init(b, 1);
       return 1;
     case BIO_C_SET_FILENAME:
       file_free(b);
-      b->shutdown = static_cast<int>(num) & BIO_CLOSE;
+      BIO_set_shutdown(b, static_cast<int>(num) & BIO_CLOSE);
       const char *mode;
       if (num & BIO_FP_APPEND) {
         if (num & BIO_FP_READ) {
@@ -195,8 +195,8 @@
         OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
         return 0;
       }
-      b->ptr = fp;
-      b->init = 1;
+      BIO_set_data(b, fp);
+      BIO_set_init(b, 1);
       return 1;
     case BIO_C_GET_FILE_PTR:
       // the ptr parameter is actually a FILE ** in this case.
@@ -206,9 +206,9 @@
       }
       return 1;
     case BIO_CTRL_GET_CLOSE:
-      return b->shutdown;
+      return BIO_get_shutdown(b);
     case BIO_CTRL_SET_CLOSE:
-      b->shutdown = static_cast<int>(num);
+      BIO_set_shutdown(b, static_cast<int>(num));
       return 1;
     case BIO_CTRL_FLUSH:
       return fflush(fp) == 0;
@@ -222,7 +222,7 @@
     return 0;
   }
 
-  if (!fgets(buf, size, (FILE *)bp->ptr)) {
+  if (!fgets(buf, size, (FILE *)BIO_get_data(bp))) {
     buf[0] = 0;
     // TODO(davidben): This doesn't distinguish error and EOF. This should check
     // |ferror| as in |file_read|.
diff --git a/crypto/bio/internal.h b/crypto/bio/internal.h
index bcff541..6c9e02e 100644
--- a/crypto/bio/internal.h
+++ b/crypto/bio/internal.h
@@ -36,6 +36,8 @@
 #endif  // !OPENSSL_NO_SOCK
 
 
+DECLARE_OPAQUE_STRUCT(bio_st, Bio)
+
 struct bio_method_st {
   int type;
   const char *name;
@@ -48,7 +50,10 @@
   long (*callback_ctrl)(BIO *, int, BIO_info_cb *);
 };
 
-struct bio_st {
+BSSL_NAMESPACE_BEGIN
+
+class Bio : public bio_st {
+ public:
   const BIO_METHOD *method;
   CRYPTO_EX_DATA ex_data;
 
@@ -71,12 +76,10 @@
   void *ptr;
   // next_bio points to the next |BIO| in a chain. This |BIO| owns a reference
   // to |next_bio|.
-  BIO *next_bio;  // used by filter BIOs
+  Bio *next_bio;  // used by filter BIOs
   uint64_t num_read, num_write;
 };
 
-BSSL_NAMESPACE_BEGIN
-
 #if !defined(OPENSSL_NO_SOCK)
 
 // bio_ip_and_port_to_socket_and_addr creates a socket and fills in |*out_addr|
diff --git a/crypto/bio/pair.cc b/crypto/bio/pair.cc
index 3ee7247..72a6f75 100644
--- a/crypto/bio/pair.cc
+++ b/crypto/bio/pair.cc
@@ -30,7 +30,7 @@
 namespace {
 struct bio_bio_st {
   BIO *peer;  // NULL if buf == NULL.
-              // If peer != NULL, then peer->ptr is also a bio_bio_st,
+              // If peer != NULL, then BIO_get_data(peer) is also a bio_bio_st,
               // and its "peer" member points back to us.
               // peer != NULL iff init != 0 in the BIO.
 
@@ -55,12 +55,12 @@
   }
 
   b->size = 17 * 1024;  // enough for one TLS record (just a default)
-  bio->ptr = b;
+  BIO_set_data(bio, b);
   return 1;
 }
 
 static void bio_destroy_pair(BIO *bio) {
-  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(bio->ptr);
+  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
   BIO *peer_bio;
   struct bio_bio_st *peer_b;
 
@@ -73,26 +73,26 @@
     return;
   }
 
-  peer_b = reinterpret_cast<bio_bio_st *>(peer_bio->ptr);
+  peer_b = reinterpret_cast<bio_bio_st *>(BIO_get_data(peer_bio));
 
   assert(peer_b != nullptr);
   assert(peer_b->peer == bio);
 
   peer_b->peer = nullptr;
-  peer_bio->init = 0;
+  BIO_set_init(peer_bio, 0);
   assert(peer_b->buf != nullptr);
   peer_b->len = 0;
   peer_b->offset = 0;
 
   b->peer = nullptr;
-  bio->init = 0;
+  BIO_set_init(bio, 0);
   assert(b->buf != nullptr);
   b->len = 0;
   b->offset = 0;
 }
 
 static int bio_free(BIO *bio) {
-  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(bio->ptr);
+  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
 
   assert(b != nullptr);
 
@@ -113,14 +113,14 @@
 
   BIO_clear_retry_flags(bio);
 
-  if (!bio->init) {
+  if (!BIO_get_init(bio)) {
     return 0;
   }
 
-  b = reinterpret_cast<bio_bio_st *>(bio->ptr);
+  b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
   assert(b != nullptr);
   assert(b->peer != nullptr);
-  peer_b = reinterpret_cast<bio_bio_st *>(b->peer->ptr);
+  peer_b = reinterpret_cast<bio_bio_st *>(BIO_get_data(b->peer));
   assert(peer_b != nullptr);
   assert(peer_b->buf != nullptr);
 
@@ -197,11 +197,11 @@
 
   BIO_clear_retry_flags(bio);
 
-  if (!bio->init || buf == nullptr || num == 0) {
+  if (!BIO_get_init(bio) || buf == nullptr || num == 0) {
     return 0;
   }
 
-  b = reinterpret_cast<bio_bio_st *>(bio->ptr);
+  b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
   assert(b != nullptr);
   assert(b->peer != nullptr);
   assert(b->buf != nullptr);
@@ -270,8 +270,8 @@
   assert(bio1 != nullptr);
   assert(bio2 != nullptr);
 
-  b1 = reinterpret_cast<bio_bio_st *>(bio1->ptr);
-  b2 = reinterpret_cast<bio_bio_st *>(bio2->ptr);
+  b1 = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio1));
+  b2 = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio2));
 
   if (b1->peer != nullptr || b2->peer != nullptr) {
     OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
@@ -309,14 +309,14 @@
   b2->closed = 0;
   b2->request = 0;
 
-  bio1->init = 1;
-  bio2->init = 1;
+  BIO_set_init(bio1, 1);
+  BIO_set_init(bio2, 1);
 
   return 1;
 }
 
 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
-  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(bio->ptr);
+  struct bio_bio_st *b = reinterpret_cast<bio_bio_st *>(BIO_get_data(bio));
   assert(b != nullptr);
   switch (cmd) {
     // Specific control codes first:
@@ -358,16 +358,16 @@
 
     // Standard control codes:
     case BIO_CTRL_GET_CLOSE:
-      return bio->shutdown;
+      return BIO_get_shutdown(bio);
 
     case BIO_CTRL_SET_CLOSE:
-      bio->shutdown = static_cast<int>(num);
+      BIO_set_shutdown(bio, static_cast<int>(num));
       return 1;
 
     case BIO_CTRL_PENDING:
       if (b->peer != nullptr) {
         struct bio_bio_st *peer_b =
-            reinterpret_cast<bio_bio_st *>(b->peer->ptr);
+            reinterpret_cast<bio_bio_st *>(BIO_get_data(b->peer));
         // TODO(crbug.com/412584975): This can overflow on 64-bit Windows.
         return static_cast<long>(peer_b->len);
       }
@@ -385,7 +385,7 @@
 
     case BIO_CTRL_EOF: {
       if (b->peer) {
-        auto *peer_b = reinterpret_cast<bio_bio_st *>(b->peer->ptr);
+        auto *peer_b = reinterpret_cast<bio_bio_st *>(BIO_get_data(b->peer));
         assert(peer_b != nullptr);
         return peer_b->len == 0 && peer_b->closed;
       }
diff --git a/crypto/bio/socket.cc b/crypto/bio/socket.cc
index 1076679..c61daec 100644
--- a/crypto/bio/socket.cc
+++ b/crypto/bio/socket.cc
@@ -36,12 +36,12 @@
 #endif
 
 static int sock_free(BIO *bio) {
-  if (bio->shutdown) {
-    if (bio->init) {
-      closesocket(bio->num);
+  if (BIO_get_shutdown(bio)) {
+    if (BIO_get_init(bio)) {
+      closesocket(FromOpaque(bio)->num);
     }
-    bio->init = 0;
-    bio->flags = 0;
+    BIO_set_init(bio, 0);
+    BIO_clear_retry_flags(bio);
   }
   return 1;
 }
@@ -53,9 +53,9 @@
 
   bio_clear_socket_error();
 #if defined(OPENSSL_WINDOWS)
-  int ret = recv(b->num, out, outl, 0);
+  int ret = recv(FromOpaque(b)->num, out, outl, 0);
 #else
-  int ret = (int)read(b->num, out, outl);
+  int ret = (int)read(FromOpaque(b)->num, out, outl);
 #endif
   BIO_clear_retry_flags(b);
   if (ret <= 0) {
@@ -69,9 +69,9 @@
 static int sock_write(BIO *b, const char *in, int inl) {
   bio_clear_socket_error();
 #if defined(OPENSSL_WINDOWS)
-  int ret = send(b->num, in, inl, 0);
+  int ret = send(FromOpaque(b)->num, in, inl, 0);
 #else
-  int ret = (int)write(b->num, in, inl);
+  int ret = (int)write(FromOpaque(b)->num, in, inl);
 #endif
   BIO_clear_retry_flags(b);
   if (ret <= 0) {
@@ -86,23 +86,23 @@
   switch (cmd) {
     case BIO_C_SET_FD:
       sock_free(b);
-      b->num = *static_cast<int *>(ptr);
-      b->shutdown = static_cast<int>(num);
-      b->init = 1;
+      FromOpaque(b)->num = *static_cast<int *>(ptr);
+      BIO_set_shutdown(b, static_cast<int>(num));
+      BIO_set_init(b, 1);
       return 1;
     case BIO_C_GET_FD:
-      if (b->init) {
-        int *out = static_cast<int*>(ptr);
+      if (BIO_get_init(b)) {
+        int *out = static_cast<int *>(ptr);
         if (out != nullptr) {
-          *out = b->num;
+          *out = FromOpaque(b)->num;
         }
-        return b->num;
+        return FromOpaque(b)->num;
       }
       return -1;
     case BIO_CTRL_GET_CLOSE:
-      return b->shutdown;
+      return BIO_get_shutdown(b);
     case BIO_CTRL_SET_CLOSE:
-      b->shutdown = static_cast<int>(num);
+      BIO_set_shutdown(b, static_cast<int>(num));
       return 1;
     case BIO_CTRL_FLUSH:
       return 1;
diff --git a/decrepit/bio/base64_bio.cc b/decrepit/bio/base64_bio.cc
index 8e1e4ce..d73b052 100644
--- a/decrepit/bio/base64_bio.cc
+++ b/decrepit/bio/base64_bio.cc
@@ -59,8 +59,8 @@
   ctx->cont = 1;
   ctx->start = 1;
 
-  bio->init = 1;
-  bio->ptr = (char *)ctx;
+  BIO_set_init(bio, 1);
+  BIO_set_data(bio, (char *)ctx);
   return 1;
 }
 
@@ -68,11 +68,11 @@
   if (bio == nullptr) {
     return 0;
   }
-  BIO_B64_CTX *ctx = (BIO_B64_CTX *)bio->ptr;
+  BIO_B64_CTX *ctx = (BIO_B64_CTX *)BIO_get_data(bio);
   Delete(ctx);
-  bio->ptr = nullptr;
-  bio->init = 0;
-  bio->flags = 0;
+  BIO_set_data(bio, nullptr);
+  BIO_set_init(bio, 0);
+  FromOpaque(bio)->flags = 0;
   return 1;
 }
 
@@ -84,9 +84,9 @@
   if (out == nullptr) {
     return 0;
   }
-  ctx = (BIO_B64_CTX *)b->ptr;
+  ctx = (BIO_B64_CTX *)BIO_get_data(b);
 
-  if (ctx == nullptr || b->next_bio == nullptr) {
+  if (ctx == nullptr || BIO_next(b) == nullptr) {
     return 0;
   }
 
@@ -128,14 +128,14 @@
       break;
     }
 
-    i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
+    i = BIO_read(BIO_next(b), &(ctx->tmp[ctx->tmp_len]),
                  B64_BLOCK_SIZE - ctx->tmp_len);
 
     if (i <= 0) {
       ret_code = i;
 
       // Should we continue next time we are called?
-      if (!BIO_should_retry(b->next_bio)) {
+      if (!BIO_should_retry(BIO_next(b))) {
         ctx->cont = i;
         // If buffer empty break
         if (ctx->tmp_len == 0) {
@@ -280,7 +280,7 @@
   int ret = 0, n, i;
   BIO_B64_CTX *ctx;
 
-  ctx = (BIO_B64_CTX *)b->ptr;
+  ctx = (BIO_B64_CTX *)BIO_get_data(b);
   BIO_clear_retry_flags(b);
 
   if (ctx->encode != B64_ENCODE) {
@@ -297,7 +297,7 @@
 
   n = ctx->buf_len - ctx->buf_off;
   while (n > 0) {
-    i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+    i = BIO_write(BIO_next(b), &(ctx->buf[ctx->buf_off]), n);
     if (i <= 0) {
       BIO_copy_next_retry(b);
       return i;
@@ -370,7 +370,7 @@
     n = ctx->buf_len;
 
     while (n > 0) {
-      i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+      i = BIO_write(BIO_next(b), &(ctx->buf[ctx->buf_off]), n);
       if (i <= 0) {
         BIO_copy_next_retry(b);
         return ret == 0 ? i : ret;
@@ -392,21 +392,21 @@
   long ret = 1;
   int i;
 
-  ctx = (BIO_B64_CTX *)b->ptr;
+  ctx = (BIO_B64_CTX *)BIO_get_data(b);
 
   switch (cmd) {
     case BIO_CTRL_RESET:
       ctx->cont = 1;
       ctx->start = 1;
       ctx->encode = B64_NONE;
-      ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+      ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
       break;
 
     case BIO_CTRL_EOF:  // More to read
       if (ctx->cont <= 0) {
         ret = 1;
       } else {
-        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
       }
       break;
 
@@ -417,7 +417,7 @@
           (ctx->base64.data_used != 0)) {
         ret = 1;
       } else if (ret <= 0) {
-        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
       }
       break;
 
@@ -425,7 +425,7 @@
       assert(ctx->buf_len >= ctx->buf_off);
       ret = ctx->buf_len - ctx->buf_off;
       if (ret <= 0) {
-        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
       }
       break;
 
@@ -453,12 +453,12 @@
         goto again;
       }
       // Finally flush the underlying BIO
-      ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+      ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
       break;
 
     case BIO_C_DO_STATE_MACHINE:
       BIO_clear_retry_flags(b);
-      ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+      ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
       BIO_copy_next_retry(b);
       break;
 
@@ -466,17 +466,17 @@
     case BIO_CTRL_GET:
     case BIO_CTRL_SET:
     default:
-      ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+      ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
       break;
   }
   return ret;
 }
 
 static long b64_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) {
-  if (b->next_bio == nullptr) {
+  if (BIO_next(b) == nullptr) {
     return 0;
   }
-  return BIO_callback_ctrl(b->next_bio, cmd, fp);
+  return BIO_callback_ctrl(BIO_next(b), cmd, fp);
 }
 
 static const BIO_METHOD b64_method = {
diff --git a/ssl/bio_ssl.cc b/ssl/bio_ssl.cc
index 90a5343..fc61e9b 100644
--- a/ssl/bio_ssl.cc
+++ b/ssl/bio_ssl.cc
@@ -19,7 +19,7 @@
 #include "../crypto/bio/internal.h"
 
 
-static SSL *get_ssl(BIO *bio) { return reinterpret_cast<SSL *>(bio->ptr); }
+static SSL *get_ssl(BIO *bio) { return reinterpret_cast<SSL *>(BIO_get_data(bio)); }
 
 static int ssl_read(BIO *bio, char *out, int outl) {
   SSL *ssl = get_ssl(bio);
@@ -111,19 +111,19 @@
       }
 
       // Note this differs from upstream OpenSSL, which synchronizes
-      // |bio->next_bio| with |ssl|'s rbio here, and on |BIO_CTRL_PUSH|. We call
+      // |BIO_next(bio)| with |ssl|'s rbio here, and on |BIO_CTRL_PUSH|. We call
       // into the corresponding |BIO| directly. (We can implement the upstream
       // behavior if it ends up necessary.)
-      bio->shutdown = static_cast<int>(num);
-      bio->ptr = ptr;
-      bio->init = 1;
+      BIO_set_shutdown(bio, static_cast<int>(num));
+      BIO_set_data(bio, ptr);
+      BIO_set_init(bio, 1);
       return 1;
 
     case BIO_CTRL_GET_CLOSE:
-      return bio->shutdown;
+      return BIO_get_shutdown(bio);
 
     case BIO_CTRL_SET_CLOSE:
-      bio->shutdown = static_cast<int>(num);
+      BIO_set_shutdown(bio, static_cast<int>(num));
       return 1;
 
     case BIO_CTRL_WPENDING:
@@ -161,7 +161,7 @@
   }
 
   SSL_shutdown(ssl);
-  if (bio->shutdown) {
+  if (BIO_get_shutdown(bio)) {
     SSL_free(ssl);
   }
 
diff --git a/util/audit_symbols.go b/util/audit_symbols.go
index 4c55e06..4d55985 100644
--- a/util/audit_symbols.go
+++ b/util/audit_symbols.go
@@ -87,7 +87,6 @@
 	regexp.MustCompile(`^vsnprintf$`),                                   // vsnprintf()
 
 	// TODO(crbug.com/42220000): Temporary symbols, to be eliminated.
-	regexp.MustCompile(`.*bio_st.*`),
 	regexp.MustCompile(`.*dh_st.*`),
 	regexp.MustCompile(`.*dsa_st.*`),
 	regexp.MustCompile(`.*ec_group_st.*`),