1 // Copyright 2017 Google Inc. 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 17 #ifndef TINK_SUBTLE_ECIES_HKDF_SENDER_KEM_BORINGSSL_H_ 18 #define TINK_SUBTLE_ECIES_HKDF_SENDER_KEM_BORINGSSL_H_ 19 20 #include <memory> 21 #include <string> 22 #include <utility> 23 24 #include "absl/strings/string_view.h" 25 #include "openssl/evp.h" 26 #include "tink/internal/fips_utils.h" 27 #include "tink/internal/ssl_unique_ptr.h" 28 #include "tink/subtle/common_enums.h" 29 #include "tink/util/secret_data.h" 30 #include "tink/util/statusor.h" 31 32 namespace crypto { 33 namespace tink { 34 namespace subtle { 35 36 // HKDF-based KEM (key encapsulation mechanism) for ECIES sender, 37 // using Boring SSL for the underlying cryptographic operations. 38 class EciesHkdfSenderKemBoringSsl { 39 public: 40 // Container for data of keys generated by the KEM. 41 class KemKey { 42 public: 43 KemKey() = default; KemKey(std::string kem_bytes,util::SecretData symmetric_key)44 explicit KemKey(std::string kem_bytes, util::SecretData symmetric_key) 45 : kem_bytes_(std::move(kem_bytes)), 46 symmetric_key_(std::move(symmetric_key)) {} 47 get_kem_bytes()48 const std::string& get_kem_bytes() const { return kem_bytes_; } 49 get_symmetric_key()50 const util::SecretData& get_symmetric_key() const { return symmetric_key_; } 51 52 private: 53 std::string kem_bytes_; 54 util::SecretData symmetric_key_; 55 }; 56 57 // Constructs a sender KEM for the specified curve and recipient's 58 // public key point. The public key's coordinates are big-endian byte array. 59 static crypto::tink::util::StatusOr< 60 std::unique_ptr<const EciesHkdfSenderKemBoringSsl>> 61 New(EllipticCurveType curve, const std::string& pubx, 62 const std::string& puby); 63 64 // Generates ephemeral key pairs, computes ECDH's shared secret based on 65 // generated ephemeral key and recipient's public key, then uses HKDF 66 // to derive the symmetric key from the shared secret, 'hkdf_info' and 67 // hkdf_salt. 68 virtual crypto::tink::util::StatusOr<std::unique_ptr<const KemKey>> 69 GenerateKey(HashType hash, absl::string_view hkdf_salt, 70 absl::string_view hkdf_info, uint32_t key_size_in_bytes, 71 EcPointFormat point_format) const = 0; 72 73 virtual ~EciesHkdfSenderKemBoringSsl() = default; 74 }; 75 76 // Implementation of EciesHkdfSenderKemBoringSsl for the NIST P-curves. 77 class EciesHkdfNistPCurveSendKemBoringSsl : public EciesHkdfSenderKemBoringSsl { 78 public: 79 // Constructs a sender KEM for the specified curve and recipient's 80 // public key point. The public key's coordinates are big-endian byte array. 81 static crypto::tink::util::StatusOr< 82 std::unique_ptr<const EciesHkdfSenderKemBoringSsl>> 83 New(EllipticCurveType curve, const std::string& pubx, 84 const std::string& puby); 85 86 // Generates ephemeral key pairs, computes ECDH's shared secret based on 87 // generated ephemeral key and recipient's public key, then uses HKDF 88 // to derive the symmetric key from the shared secret, 'hkdf_info' and 89 // hkdf_salt. 90 crypto::tink::util::StatusOr<std::unique_ptr<const KemKey>> GenerateKey( 91 HashType hash, absl::string_view hkdf_salt, absl::string_view hkdf_info, 92 uint32_t key_size_in_bytes, EcPointFormat point_format) const override; 93 94 static constexpr crypto::tink::internal::FipsCompatibility kFipsStatus = 95 crypto::tink::internal::FipsCompatibility::kNotFips; 96 97 private: 98 EciesHkdfNistPCurveSendKemBoringSsl( 99 EllipticCurveType curve, const std::string& pubx, const std::string& puby, 100 internal::SslUniquePtr<EC_POINT> peer_pub_key); 101 102 EllipticCurveType curve_; 103 std::string pubx_; 104 std::string puby_; 105 internal::SslUniquePtr<EC_POINT> peer_pub_key_; 106 }; 107 108 // Implementation of EciesHkdfSenderKemBoringSsl for curve25519. 109 class EciesHkdfX25519SendKemBoringSsl : public EciesHkdfSenderKemBoringSsl { 110 public: 111 // Constructs a sender KEM for the specified curve and recipient's 112 // public key point. The public key's coordinates are big-endian byte array. 113 static crypto::tink::util::StatusOr< 114 std::unique_ptr<const EciesHkdfSenderKemBoringSsl>> 115 New(EllipticCurveType curve, const std::string& pubx, 116 const std::string& puby); 117 118 // Generates ephemeral key pairs, computes ECDH's shared secret based on 119 // generated ephemeral key and recipient's public key, then uses HKDF 120 // to derive the symmetric key from the shared secret, 'hkdf_info' and 121 // hkdf_salt. 122 crypto::tink::util::StatusOr<std::unique_ptr<const KemKey>> GenerateKey( 123 HashType hash, absl::string_view hkdf_salt, absl::string_view hkdf_info, 124 uint32_t key_size_in_bytes, EcPointFormat point_format) const override; 125 126 static constexpr crypto::tink::internal::FipsCompatibility kFipsStatus = 127 crypto::tink::internal::FipsCompatibility::kNotFips; 128 129 private: 130 explicit EciesHkdfX25519SendKemBoringSsl( 131 internal::SslUniquePtr<EVP_PKEY> peer_public_key); 132 133 const internal::SslUniquePtr<EVP_PKEY> peer_public_key_; 134 }; 135 136 } // namespace subtle 137 } // namespace tink 138 } // namespace crypto 139 140 #endif // TINK_SUBTLE_ECIES_HKDF_SENDER_KEM_BORINGSSL_H_ 141