|
|
|
/* Copyright (c) 2016, Google Inc.
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
|
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
|
|
|
|
|
|
#include <openssl/pool.h>
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <openssl/bytestring.h>
|
|
|
|
#include <openssl/mem.h>
|
|
|
|
#include <openssl/rand.h>
|
|
|
|
#include <openssl/siphash.h>
|
|
|
|
#include <openssl/thread.h>
|
|
|
|
|
|
|
|
#include "../internal.h"
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
|
|
|
|
static uint32_t CRYPTO_BUFFER_hash(const CRYPTO_BUFFER *buf) {
|
|
|
|
return (uint32_t)SIPHASH_24(buf->pool->hash_key, buf->data, buf->len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int CRYPTO_BUFFER_cmp(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b) {
|
|
|
|
// Only |CRYPTO_BUFFER|s from the same pool have compatible hashes.
|
|
|
|
assert(a->pool != NULL);
|
|
|
|
assert(a->pool == b->pool);
|
|
|
|
if (a->len != b->len) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return OPENSSL_memcmp(a->data, b->data, a->len);
|
|
|
|
}
|
|
|
|
|
|
|
|
CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void) {
|
|
|
|
CRYPTO_BUFFER_POOL *pool = OPENSSL_malloc(sizeof(CRYPTO_BUFFER_POOL));
|
|
|
|
if (pool == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
OPENSSL_memset(pool, 0, sizeof(CRYPTO_BUFFER_POOL));
|
|
|
|
pool->bufs = lh_CRYPTO_BUFFER_new(CRYPTO_BUFFER_hash, CRYPTO_BUFFER_cmp);
|
|
|
|
if (pool->bufs == NULL) {
|
|
|
|
OPENSSL_free(pool);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRYPTO_MUTEX_init(&pool->lock);
|
|
|
|
RAND_bytes((uint8_t *)&pool->hash_key, sizeof(pool->hash_key));
|
|
|
|
|
|
|
|
return pool;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool) {
|
|
|
|
if (pool == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !defined(NDEBUG)
|
|
|
|
CRYPTO_MUTEX_lock_write(&pool->lock);
|
|
|
|
assert(lh_CRYPTO_BUFFER_num_items(pool->bufs) == 0);
|
|
|
|
CRYPTO_MUTEX_unlock_write(&pool->lock);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
lh_CRYPTO_BUFFER_free(pool->bufs);
|
|
|
|
CRYPTO_MUTEX_cleanup(&pool->lock);
|
|
|
|
OPENSSL_free(pool);
|
|
|
|
}
|
|
|
|
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
static void crypto_buffer_free_object(CRYPTO_BUFFER *buf) {
|
|
|
|
if (!buf->data_is_static) {
|
|
|
|
OPENSSL_free(buf->data);
|
|
|
|
}
|
|
|
|
OPENSSL_free(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static CRYPTO_BUFFER *crypto_buffer_new(const uint8_t *data, size_t len,
|
|
|
|
int data_is_static,
|
|
|
|
CRYPTO_BUFFER_POOL *pool) {
|
|
|
|
if (pool != NULL) {
|
|
|
|
CRYPTO_BUFFER tmp;
|
|
|
|
tmp.data = (uint8_t *) data;
|
|
|
|
tmp.len = len;
|
|
|
|
tmp.pool = pool;
|
|
|
|
|
|
|
|
CRYPTO_MUTEX_lock_read(&pool->lock);
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, &tmp);
|
|
|
|
if (data_is_static && duplicate != NULL && !duplicate->data_is_static) {
|
|
|
|
// If the new |CRYPTO_BUFFER| would have static data, but the duplicate
|
|
|
|
// does not, we replace the old one with the new static version.
|
|
|
|
duplicate = NULL;
|
|
|
|
}
|
|
|
|
if (duplicate != NULL) {
|
|
|
|
CRYPTO_refcount_inc(&duplicate->references);
|
|
|
|
}
|
|
|
|
CRYPTO_MUTEX_unlock_read(&pool->lock);
|
|
|
|
|
|
|
|
if (duplicate != NULL) {
|
|
|
|
return duplicate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER));
|
|
|
|
if (buf == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER));
|
|
|
|
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
if (data_is_static) {
|
|
|
|
buf->data = (uint8_t *)data;
|
|
|
|
buf->data_is_static = 1;
|
|
|
|
} else {
|
|
|
|
buf->data = OPENSSL_memdup(data, len);
|
|
|
|
if (len != 0 && buf->data == NULL) {
|
|
|
|
OPENSSL_free(buf);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
buf->len = len;
|
|
|
|
buf->references = 1;
|
|
|
|
|
|
|
|
if (pool == NULL) {
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf->pool = pool;
|
|
|
|
|
|
|
|
CRYPTO_MUTEX_lock_write(&pool->lock);
|
|
|
|
CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, buf);
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
if (data_is_static && duplicate != NULL && !duplicate->data_is_static) {
|
|
|
|
// If the new |CRYPTO_BUFFER| would have static data, but the duplicate does
|
|
|
|
// not, we replace the old one with the new static version.
|
|
|
|
duplicate = NULL;
|
|
|
|
}
|
|
|
|
int inserted = 0;
|
|
|
|
if (duplicate == NULL) {
|
|
|
|
CRYPTO_BUFFER *old = NULL;
|
|
|
|
inserted = lh_CRYPTO_BUFFER_insert(pool->bufs, &old, buf);
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
// |old| may be non-NULL if a match was found but ignored. |pool->bufs| does
|
|
|
|
// not increment refcounts, so there is no need to clean up after the
|
|
|
|
// replacement.
|
|
|
|
} else {
|
|
|
|
CRYPTO_refcount_inc(&duplicate->references);
|
|
|
|
}
|
|
|
|
CRYPTO_MUTEX_unlock_write(&pool->lock);
|
|
|
|
|
|
|
|
if (!inserted) {
|
|
|
|
// We raced to insert |buf| into the pool and lost, or else there was an
|
|
|
|
// error inserting.
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
crypto_buffer_free_object(buf);
|
|
|
|
return duplicate;
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len,
|
|
|
|
CRYPTO_BUFFER_POOL *pool) {
|
|
|
|
return crypto_buffer_new(data, len, /*data_is_static=*/0, pool);
|
|
|
|
}
|
|
|
|
|
|
|
|
CRYPTO_BUFFER *CRYPTO_BUFFER_alloc(uint8_t **out_data, size_t len) {
|
|
|
|
CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER));
|
|
|
|
if (buf == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER));
|
|
|
|
|
|
|
|
buf->data = OPENSSL_malloc(len);
|
|
|
|
if (len != 0 && buf->data == NULL) {
|
|
|
|
OPENSSL_free(buf);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
buf->len = len;
|
|
|
|
buf->references = 1;
|
|
|
|
|
|
|
|
*out_data = buf->data;
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_CBS(const CBS *cbs,
|
|
|
|
CRYPTO_BUFFER_POOL *pool) {
|
|
|
|
return CRYPTO_BUFFER_new(CBS_data(cbs), CBS_len(cbs), pool);
|
|
|
|
}
|
|
|
|
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_static_data_unsafe(
|
|
|
|
const uint8_t *data, size_t len, CRYPTO_BUFFER_POOL *pool) {
|
|
|
|
return crypto_buffer_new(data, len, /*data_is_static=*/1, pool);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf) {
|
|
|
|
if (buf == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRYPTO_BUFFER_POOL *const pool = buf->pool;
|
|
|
|
if (pool == NULL) {
|
|
|
|
if (CRYPTO_refcount_dec_and_test_zero(&buf->references)) {
|
|
|
|
// If a reference count of zero is observed, there cannot be a reference
|
|
|
|
// from any pool to this buffer and thus we are able to free this
|
|
|
|
// buffer.
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
crypto_buffer_free_object(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRYPTO_MUTEX_lock_write(&pool->lock);
|
|
|
|
if (!CRYPTO_refcount_dec_and_test_zero(&buf->references)) {
|
|
|
|
CRYPTO_MUTEX_unlock_write(&buf->pool->lock);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We have an exclusive lock on the pool, therefore no concurrent lookups can
|
|
|
|
// find this buffer and increment the reference count. Thus, if the count is
|
|
|
|
// zero there are and can never be any more references and thus we can free
|
|
|
|
// this buffer.
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
//
|
|
|
|
// Note it is possible |buf| is no longer in the pool, if it was replaced by a
|
|
|
|
// static version. If that static version was since removed, it is even
|
|
|
|
// possible for |found| to be NULL.
|
|
|
|
CRYPTO_BUFFER *found = lh_CRYPTO_BUFFER_retrieve(pool->bufs, buf);
|
|
|
|
if (found == buf) {
|
|
|
|
found = lh_CRYPTO_BUFFER_delete(pool->bufs, buf);
|
|
|
|
assert(found == buf);
|
|
|
|
(void)found;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRYPTO_MUTEX_unlock_write(&buf->pool->lock);
|
Add CRYPTO_BUFFER_new_from_static_data_unsafe.
When making a CRYPTO_BUFFER from a static, const buffer, there is no
need to make a copy of the data. Instead, we can reference it directly.
The hope is this will save a bit of memory in Chromium, since root store
certs will already in static data.
Moreover, by letting static CRYPTO_BUFFERs participate in pooling, we
can extend the memory savings to yet other copies of these certs. For
instance, if we make the root store updatable via component updater,
most of the updated roots will likely already be in the binary's copy.
Pooling will transparently dedup those and avoid retaining an extra
copy.
(I haven't gone as far as to give static CRYPTO_BUFFERs strong
references from the pool, since that seems odd. But something like
Chromium probably wants to intentionally leak the initial static ones so
that, when all references go away, they're still available for pooling.)
Change-Id: I05c25c5ff618f9f7a6ed21e4575cf659e7c32811
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50045
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
3 years ago
|
|
|
crypto_buffer_free_object(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf) {
|
|
|
|
// This is safe in the case that |buf->pool| is NULL because it's just
|
|
|
|
// standard reference counting in that case.
|
|
|
|
//
|
|
|
|
// This is also safe if |buf->pool| is non-NULL because, if it were racing
|
|
|
|
// with |CRYPTO_BUFFER_free| then the two callers must have independent
|
|
|
|
// references already and so the reference count will never hit zero.
|
|
|
|
CRYPTO_refcount_inc(&buf->references);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf) {
|
|
|
|
return buf->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf) {
|
|
|
|
return buf->len;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out) {
|
|
|
|
CBS_init(out, buf->data, buf->len);
|
|
|
|
}
|