123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/webcrypto/algorithms/util.h"
- #include "base/check_op.h"
- #include "components/webcrypto/status.h"
- #include "crypto/openssl_util.h"
- #include "third_party/boringssl/src/include/openssl/aead.h"
- #include "third_party/boringssl/src/include/openssl/bn.h"
- #include "third_party/boringssl/src/include/openssl/digest.h"
- namespace webcrypto {
- const EVP_MD* GetDigest(const blink::WebCryptoAlgorithm& hash_algorithm) {
- return GetDigest(hash_algorithm.Id());
- }
- const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id) {
- switch (id) {
- case blink::kWebCryptoAlgorithmIdSha1:
- return EVP_sha1();
- case blink::kWebCryptoAlgorithmIdSha256:
- return EVP_sha256();
- case blink::kWebCryptoAlgorithmIdSha384:
- return EVP_sha384();
- case blink::kWebCryptoAlgorithmIdSha512:
- return EVP_sha512();
- default:
- return nullptr;
- }
- }
- void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes) {
- size_t length_bytes = NumBitsToBytes(length_bits);
- if (bytes->size() != length_bytes) {
- CHECK_LT(length_bytes, bytes->size());
- bytes->resize(length_bytes);
- }
- size_t remainder_bits = length_bits % 8;
- // Zero any "unused bits" in the final byte.
- if (remainder_bits)
- bytes->back() &= ~((0xFF) >> remainder_bits);
- }
- Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
- blink::WebCryptoKeyUsageMask actual_usages) {
- if (!ContainsKeyUsages(all_possible_usages, actual_usages))
- return Status::ErrorCreateKeyBadUsages();
- return Status::Success();
- }
- bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
- blink::WebCryptoKeyUsageMask b) {
- return (a & b) == b;
- }
- Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
- base::span<const uint8_t> raw_key,
- base::span<const uint8_t> data,
- unsigned int tag_length_bytes,
- base::span<const uint8_t> iv,
- base::span<const uint8_t> additional_data,
- const EVP_AEAD* aead_alg,
- std::vector<uint8_t>* buffer) {
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
- bssl::ScopedEVP_AEAD_CTX ctx;
- if (!aead_alg)
- return Status::ErrorUnexpected();
- if (!EVP_AEAD_CTX_init(ctx.get(), aead_alg, raw_key.data(), raw_key.size(),
- tag_length_bytes, nullptr)) {
- return Status::OperationError();
- }
- size_t len;
- int ok;
- if (mode == DECRYPT) {
- if (data.size() < tag_length_bytes)
- return Status::ErrorDataTooSmall();
- buffer->resize(data.size() - tag_length_bytes);
- ok = EVP_AEAD_CTX_open(ctx.get(), buffer->data(), &len, buffer->size(),
- iv.data(), iv.size(), data.data(), data.size(),
- additional_data.data(), additional_data.size());
- } else {
- // No need to check for unsigned integer overflow here (seal fails if
- // the output buffer is too small).
- buffer->resize(data.size() + EVP_AEAD_max_overhead(aead_alg));
- ok = EVP_AEAD_CTX_seal(ctx.get(), buffer->data(), &len, buffer->size(),
- iv.data(), iv.size(), data.data(), data.size(),
- additional_data.data(), additional_data.size());
- }
- if (!ok)
- return Status::OperationError();
- buffer->resize(len);
- return Status::Success();
- }
- } // namespace webcrypto
|