1 // Copyright 2018 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 /////////////////////////////////////////////////////////////////////////////// 16 #ifndef TINK_AEAD_AES_EAX_KEY_MANAGER_H_ 17 #define TINK_AEAD_AES_EAX_KEY_MANAGER_H_ 18 19 #include <stdint.h> 20 21 #include <memory> 22 #include <string> 23 24 #include "absl/memory/memory.h" 25 #include "absl/status/status.h" 26 #include "absl/strings/str_cat.h" 27 #include "tink/aead.h" 28 #include "tink/core/key_type_manager.h" 29 #include "tink/core/template_util.h" 30 #include "tink/subtle/aes_eax_boringssl.h" 31 #include "tink/subtle/random.h" 32 #include "tink/util/constants.h" 33 #include "tink/util/secret_data.h" 34 #include "tink/util/status.h" 35 #include "tink/util/statusor.h" 36 #include "tink/util/validation.h" 37 #include "proto/aes_eax.pb.h" 38 #include "proto/tink.pb.h" 39 40 namespace crypto { 41 namespace tink { 42 43 class AesEaxKeyManager 44 : public KeyTypeManager<google::crypto::tink::AesEaxKey, 45 google::crypto::tink::AesEaxKeyFormat, List<Aead>> { 46 public: 47 class AeadFactory : public PrimitiveFactory<Aead> { Create(const google::crypto::tink::AesEaxKey & key)48 crypto::tink::util::StatusOr<std::unique_ptr<Aead>> Create( 49 const google::crypto::tink::AesEaxKey& key) const override { 50 return subtle::AesEaxBoringSsl::New( 51 util::SecretDataFromStringView(key.key_value()), 52 key.params().iv_size()); 53 } 54 }; 55 AesEaxKeyManager()56 AesEaxKeyManager() : KeyTypeManager(absl::make_unique<AeadFactory>()) {} 57 get_version()58 uint32_t get_version() const override { return 0; } 59 key_material_type()60 google::crypto::tink::KeyData::KeyMaterialType key_material_type() 61 const override { 62 return google::crypto::tink::KeyData::SYMMETRIC; 63 } 64 get_key_type()65 const std::string& get_key_type() const override { return key_type_; } 66 ValidateKey(const google::crypto::tink::AesEaxKey & key)67 crypto::tink::util::Status ValidateKey( 68 const google::crypto::tink::AesEaxKey& key) const override { 69 crypto::tink::util::Status status = 70 ValidateVersion(key.version(), get_version()); 71 if (!status.ok()) return status; 72 status = ValidateKeySize(key.key_value().size()); 73 if (!status.ok()) return status; 74 return ValidateIvSize(key.params().iv_size()); 75 } 76 ValidateKeyFormat(const google::crypto::tink::AesEaxKeyFormat & key_format)77 crypto::tink::util::Status ValidateKeyFormat( 78 const google::crypto::tink::AesEaxKeyFormat& key_format) const override { 79 crypto::tink::util::Status status = ValidateKeySize(key_format.key_size()); 80 if (!status.ok()) return status; 81 return ValidateIvSize(key_format.params().iv_size()); 82 } 83 CreateKey(const google::crypto::tink::AesEaxKeyFormat & key_format)84 crypto::tink::util::StatusOr<google::crypto::tink::AesEaxKey> CreateKey( 85 const google::crypto::tink::AesEaxKeyFormat& key_format) const override { 86 google::crypto::tink::AesEaxKey aes_eax_key; 87 aes_eax_key.set_version(get_version()); 88 aes_eax_key.set_key_value( 89 subtle::Random::GetRandomBytes(key_format.key_size())); 90 aes_eax_key.mutable_params()->set_iv_size( 91 key_format.params().iv_size()); 92 return aes_eax_key; 93 } 94 95 private: ValidateKeySize(uint32_t key_size)96 crypto::tink::util::Status ValidateKeySize(uint32_t key_size) const { 97 if (key_size != 16 && key_size != 32) { 98 return crypto::tink::util::Status( 99 absl::StatusCode::kInvalidArgument, 100 absl::StrCat("Invalid key size: ", key_size, 101 " bytes, expected 16 or 32 bytes.")); 102 } 103 return crypto::tink::util::OkStatus(); 104 } 105 ValidateIvSize(uint32_t iv_size)106 crypto::tink::util::Status ValidateIvSize(uint32_t iv_size) const { 107 if (iv_size != 12 && iv_size != 16) { 108 return crypto::tink::util::Status( 109 absl::StatusCode::kInvalidArgument, 110 absl::StrCat("Invalid IV size: ", iv_size, 111 " bytes, expected 12 or 16 bytes.")); 112 } 113 return crypto::tink::util::OkStatus(); 114 } 115 116 const std::string key_type_ = absl::StrCat( 117 kTypeGoogleapisCom, google::crypto::tink::AesEaxKey().GetTypeName()); 118 }; 119 120 } // namespace tink 121 } // namespace crypto 122 123 #endif // TINK_AEAD_AES_EAX_KEY_MANAGER_H_ 124