// Copyright 2016 The BoringSSL Authors // // Licensed 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 // // https://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. #ifndef OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H #define OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H #include "../internal.h" #include "../lhash/internal.h" #include "../mem_internal.h" DECLARE_OPAQUE_STRUCT(crypto_buffer_st, CryptoBuffer) DECLARE_OPAQUE_STRUCT(crypto_buffer_pool_st, CryptoBufferPool) BSSL_NAMESPACE_BEGIN // A CryptoBufferPoolHandle is the portion of the pool that lasts as long as any // live buffer or pool. This allows buffers to outlive the pool. (The pool is // only needed as long as callers wish to create new buffers.) class CryptoBufferPoolHandle : public RefCounted { public: explicit CryptoBufferPoolHandle(CryptoBufferPool *pool) : RefCounted(CheckSubClass()), pool_(pool) {} // pool_ is protected by lock_. Mutex lock_; CryptoBufferPool *pool_ = nullptr; private: friend RefCounted; ~CryptoBufferPoolHandle() = default; }; class CryptoBuffer : public crypto_buffer_st { public: CryptoBuffer() = default; CryptoBuffer(const CryptoBuffer &) = delete; CryptoBuffer &operator=(const CryptoBuffer &) = delete; Span span() const { return Span(data_, len_); } // Instead of subclassing RefCounted, implement refcounting by hand. // CryptoBuffer's refcounting must synchronize with CryptoBufferPool. static constexpr bool kAllowRefCountedUniquePtr = true; void UpRefInternal(); void DecRefInternal(); UniquePtr pool_handle_; uint8_t *data_ = nullptr; size_t len_ = 0; CRYPTO_refcount_t references_ = 1; bool data_is_static_ = false; private: ~CryptoBuffer(); }; DEFINE_LHASH_OF(CryptoBuffer) class CryptoBufferPool : public crypto_buffer_pool_st { public: static constexpr bool kAllowUniquePtr = true; CryptoBufferPool(); ~CryptoBufferPool(); // Hash returns the hash of |data|. uint32_t Hash(Span data) const; // FindBufferLocked looks for a buffer with hash |hash| and contents |data|. // It returns it if found and nullptr otherwise. |handle_->lock_| must be // locked for reading or writing before calling this. CryptoBuffer *FindBufferLocked(uint32_t hash, Span data); UniquePtr handle_; LHASH_OF(CryptoBuffer) *bufs_ = nullptr; uint64_t hash_key_[2]; }; BSSL_NAMESPACE_END #endif // OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H