aes_gcm.cc 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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 <stddef.h>
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <vector>
  8. #include "components/webcrypto/algorithms/aes.h"
  9. #include "components/webcrypto/algorithms/util.h"
  10. #include "components/webcrypto/blink_key_handle.h"
  11. #include "components/webcrypto/status.h"
  12. #include "crypto/openssl_util.h"
  13. #include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
  14. #include "third_party/boringssl/src/include/openssl/aead.h"
  15. namespace webcrypto {
  16. namespace {
  17. const EVP_AEAD* GetAesGcmAlgorithmFromKeySize(size_t key_size_bytes) {
  18. switch (key_size_bytes) {
  19. case 16:
  20. return EVP_aead_aes_128_gcm();
  21. case 32:
  22. return EVP_aead_aes_256_gcm();
  23. default:
  24. return nullptr;
  25. }
  26. }
  27. Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode,
  28. const blink::WebCryptoAlgorithm& algorithm,
  29. const blink::WebCryptoKey& key,
  30. base::span<const uint8_t> data,
  31. std::vector<uint8_t>* buffer) {
  32. const std::vector<uint8_t>& raw_key = GetSymmetricKeyData(key);
  33. const blink::WebCryptoAesGcmParams* params = algorithm.AesGcmParams();
  34. // The WebCrypto spec defines the default value for the tag length, as well as
  35. // the allowed values for tag length.
  36. unsigned int tag_length_bits = 128;
  37. if (params->HasTagLengthBits()) {
  38. tag_length_bits = params->OptionalTagLengthBits();
  39. if (tag_length_bits != 32 && tag_length_bits != 64 &&
  40. tag_length_bits != 96 && tag_length_bits != 104 &&
  41. tag_length_bits != 112 && tag_length_bits != 120 &&
  42. tag_length_bits != 128) {
  43. return Status::ErrorInvalidAesGcmTagLength();
  44. }
  45. }
  46. return AeadEncryptDecrypt(mode, raw_key, data, tag_length_bits / 8,
  47. params->Iv(), params->OptionalAdditionalData(),
  48. GetAesGcmAlgorithmFromKeySize(raw_key.size()),
  49. buffer);
  50. }
  51. class AesGcmImplementation : public AesAlgorithm {
  52. public:
  53. AesGcmImplementation() : AesAlgorithm("GCM") {}
  54. Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
  55. const blink::WebCryptoKey& key,
  56. base::span<const uint8_t> data,
  57. std::vector<uint8_t>* buffer) const override {
  58. return AesGcmEncryptDecrypt(ENCRYPT, algorithm, key, data, buffer);
  59. }
  60. Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
  61. const blink::WebCryptoKey& key,
  62. base::span<const uint8_t> data,
  63. std::vector<uint8_t>* buffer) const override {
  64. return AesGcmEncryptDecrypt(DECRYPT, algorithm, key, data, buffer);
  65. }
  66. };
  67. } // namespace
  68. std::unique_ptr<AlgorithmImplementation> CreateAesGcmImplementation() {
  69. return std::make_unique<AesGcmImplementation>();
  70. }
  71. } // namespace webcrypto