util.cc 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/webcrypto/algorithms/util.h"
  5. #include "base/check_op.h"
  6. #include "components/webcrypto/status.h"
  7. #include "crypto/openssl_util.h"
  8. #include "third_party/boringssl/src/include/openssl/aead.h"
  9. #include "third_party/boringssl/src/include/openssl/bn.h"
  10. #include "third_party/boringssl/src/include/openssl/digest.h"
  11. namespace webcrypto {
  12. const EVP_MD* GetDigest(const blink::WebCryptoAlgorithm& hash_algorithm) {
  13. return GetDigest(hash_algorithm.Id());
  14. }
  15. const EVP_MD* GetDigest(blink::WebCryptoAlgorithmId id) {
  16. switch (id) {
  17. case blink::kWebCryptoAlgorithmIdSha1:
  18. return EVP_sha1();
  19. case blink::kWebCryptoAlgorithmIdSha256:
  20. return EVP_sha256();
  21. case blink::kWebCryptoAlgorithmIdSha384:
  22. return EVP_sha384();
  23. case blink::kWebCryptoAlgorithmIdSha512:
  24. return EVP_sha512();
  25. default:
  26. return nullptr;
  27. }
  28. }
  29. void TruncateToBitLength(size_t length_bits, std::vector<uint8_t>* bytes) {
  30. size_t length_bytes = NumBitsToBytes(length_bits);
  31. if (bytes->size() != length_bytes) {
  32. CHECK_LT(length_bytes, bytes->size());
  33. bytes->resize(length_bytes);
  34. }
  35. size_t remainder_bits = length_bits % 8;
  36. // Zero any "unused bits" in the final byte.
  37. if (remainder_bits)
  38. bytes->back() &= ~((0xFF) >> remainder_bits);
  39. }
  40. Status CheckKeyCreationUsages(blink::WebCryptoKeyUsageMask all_possible_usages,
  41. blink::WebCryptoKeyUsageMask actual_usages) {
  42. if (!ContainsKeyUsages(all_possible_usages, actual_usages))
  43. return Status::ErrorCreateKeyBadUsages();
  44. return Status::Success();
  45. }
  46. bool ContainsKeyUsages(blink::WebCryptoKeyUsageMask a,
  47. blink::WebCryptoKeyUsageMask b) {
  48. return (a & b) == b;
  49. }
  50. Status AeadEncryptDecrypt(EncryptOrDecrypt mode,
  51. base::span<const uint8_t> raw_key,
  52. base::span<const uint8_t> data,
  53. unsigned int tag_length_bytes,
  54. base::span<const uint8_t> iv,
  55. base::span<const uint8_t> additional_data,
  56. const EVP_AEAD* aead_alg,
  57. std::vector<uint8_t>* buffer) {
  58. crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
  59. bssl::ScopedEVP_AEAD_CTX ctx;
  60. if (!aead_alg)
  61. return Status::ErrorUnexpected();
  62. if (!EVP_AEAD_CTX_init(ctx.get(), aead_alg, raw_key.data(), raw_key.size(),
  63. tag_length_bytes, nullptr)) {
  64. return Status::OperationError();
  65. }
  66. size_t len;
  67. int ok;
  68. if (mode == DECRYPT) {
  69. if (data.size() < tag_length_bytes)
  70. return Status::ErrorDataTooSmall();
  71. buffer->resize(data.size() - tag_length_bytes);
  72. ok = EVP_AEAD_CTX_open(ctx.get(), buffer->data(), &len, buffer->size(),
  73. iv.data(), iv.size(), data.data(), data.size(),
  74. additional_data.data(), additional_data.size());
  75. } else {
  76. // No need to check for unsigned integer overflow here (seal fails if
  77. // the output buffer is too small).
  78. buffer->resize(data.size() + EVP_AEAD_max_overhead(aead_alg));
  79. ok = EVP_AEAD_CTX_seal(ctx.get(), buffer->data(), &len, buffer->size(),
  80. iv.data(), iv.size(), data.data(), data.size(),
  81. additional_data.data(), additional_data.size());
  82. }
  83. if (!ok)
  84. return Status::OperationError();
  85. buffer->resize(len);
  86. return Status::Success();
  87. }
  88. } // namespace webcrypto