| // Copyright 2017 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #ifndef TINK_SUBTLE_SUBTLE_UTIL_BORINGSSL_H_ |
| #define TINK_SUBTLE_SUBTLE_UTIL_BORINGSSL_H_ |
| |
| #include <cstdint> |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "absl/base/attributes.h" |
| #include "absl/base/macros.h" |
| #include "absl/strings/string_view.h" |
| #include "openssl/bn.h" |
| #include "openssl/evp.h" |
| #include "tink/aead/internal/aead_util.h" |
| #include "tink/internal/aes_util.h" |
| #include "tink/internal/bn_util.h" |
| #include "tink/internal/ec_util.h" |
| #include "tink/internal/err_util.h" |
| #include "tink/internal/md_util.h" |
| #include "tink/internal/rsa_util.h" |
| #include "tink/internal/ssl_unique_ptr.h" |
| #include "tink/internal/util.h" |
| #include "tink/subtle/common_enums.h" |
| #include "tink/util/secret_data.h" |
| #include "tink/util/status.h" |
| #include "tink/util/statusor.h" |
| |
| namespace crypto { |
| namespace tink { |
| namespace subtle { |
| |
| class SubtleUtilBoringSSL { |
| public: |
| using EcKey ABSL_DEPRECATED("Use of this type is dicouraged outside Tink.") = |
| internal::EcKey; |
| using X25519Key ABSL_DEPRECATED( |
| "Use of this type is dicouraged outside Tink.") = internal::X25519Key; |
| using Ed25519Key ABSL_DEPRECATED( |
| "Use of this type is dicouraged outside Tink.") = internal::Ed25519Key; |
| using RsaPublicKey ABSL_DEPRECATED( |
| "Use of this type is dicouraged outside Tink.") = internal::RsaPublicKey; |
| using RsaSsaPssParams ABSL_DEPRECATED( |
| "Use of this type is dicouraged outside Tink.") = |
| internal::RsaSsaPssParams; |
| using RsaSsaPkcs1Params ABSL_DEPRECATED( |
| "Use of this type is dicouraged outside Tink.") = |
| internal::RsaSsaPkcs1Params; |
| using RsaPrivateKey ABSL_DEPRECATED( |
| "Use of this type is dicouraged outside Tink.") = internal::RsaPrivateKey; |
| |
| // Returns BoringSSL's BIGNUM constructed from bigendian string |
| // representation. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::StatusOr<internal::SslUniquePtr<BIGNUM>> str2bn( |
| absl::string_view s) { |
| return internal::StringToBignum(s); |
| } |
| |
| // Returns a SecretData of size 'len' that holds BIGNUM 'bn'. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::StatusOr<std::string> bn2str(const BIGNUM *bn, |
| size_t len) { |
| return internal::BignumToString(bn, len); |
| } |
| |
| // Returns a string of size 'len' that holds BIGNUM 'bn'. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::StatusOr<util::SecretData> BignumToSecretData( |
| const BIGNUM *bn, size_t len) { |
| return internal::BignumToSecretData(bn, len); |
| } |
| |
| // Returns BoringSSL error strings accumulated in the error queue, |
| // thus emptying the queue. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline std::string GetErrors() { return internal::GetSslErrors(); } |
| |
| // Returns BoringSSL's EC_GROUP constructed from the curve type. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<EC_GROUP *> GetEcGroup( |
| EllipticCurveType curve_type) { |
| util::StatusOr<internal::SslUniquePtr<EC_GROUP>> ec_group = |
| internal::EcGroupFromCurveType(curve_type); |
| if (!ec_group.ok()) { |
| return ec_group.status(); |
| } |
| return ec_group->release(); |
| } |
| |
| // Returns the curve type associated with the EC_GROUP |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<EllipticCurveType> GetCurve( |
| const EC_GROUP *group) { |
| return internal::CurveTypeFromEcGroup(group); |
| } |
| |
| // Returns BoringSSL's EC_POINT constructed from the curve type, big-endian |
| // representation of public key's x-coordinate and y-coordinate. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<EC_POINT *> GetEcPoint( |
| EllipticCurveType curve, absl::string_view pubx, absl::string_view puby) { |
| util::StatusOr<internal::SslUniquePtr<EC_POINT>> ec_point = |
| internal::GetEcPoint(curve, pubx, puby); |
| if (!ec_point.ok()) { |
| return ec_point.status(); |
| } |
| return ec_point->release(); |
| } |
| |
| // Returns a new EC key for the specified curve. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<EcKey> GetNewEcKey( |
| EllipticCurveType curve_type) { |
| return internal::NewEcKey(curve_type); |
| } |
| |
| // Returns a new EC key for the specified curve derived from a seed. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<EcKey> GetNewEcKeyFromSeed( |
| EllipticCurveType curve_type, const util::SecretData &secret_seed) { |
| return internal::NewEcKey(curve_type, secret_seed); |
| } |
| |
| // Returns a new X25519 key, or nullptr if generation fails. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline std::unique_ptr<X25519Key> GenerateNewX25519Key() { |
| util::StatusOr<std::unique_ptr<internal::X25519Key>> key = |
| internal::NewX25519Key(); |
| if (!key.ok()) { |
| return nullptr; |
| } |
| return *std::move(key); |
| } |
| |
| // Returns a X25519Key matching the specified EcKey. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<std::unique_ptr<X25519Key>> |
| X25519KeyFromEcKey(const EcKey &ec_key) { |
| return internal::X25519KeyFromEcKey(ec_key); |
| } |
| |
| // Returns an EcKey matching the specified X25519Key. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline EcKey EcKeyFromX25519Key(const X25519Key *x25519_key) { |
| return internal::EcKeyFromX25519Key(x25519_key); |
| } |
| |
| // Returns a new ED25519 key. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline std::unique_ptr<Ed25519Key> GetNewEd25519Key() { |
| util::StatusOr<std::unique_ptr<Ed25519Key>> key = internal::NewEd25519Key(); |
| if (!key.ok()) { |
| return nullptr; |
| } |
| return *std::move(key); |
| } |
| |
| // Returns a new ED25519 key generated from a 32-byte secret seed. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline std::unique_ptr<Ed25519Key> GetNewEd25519KeyFromSeed( |
| const util::SecretData &secret_seed) { |
| util::StatusOr<std::unique_ptr<Ed25519Key>> key = |
| internal::NewEd25519Key(secret_seed); |
| if (!key.ok()) { |
| return nullptr; |
| } |
| return *std::move(key); |
| } |
| |
| // Returns BoringSSL's EC_POINT constructed from curve type, point format and |
| // encoded public key's point. The uncompressed point is encoded as |
| // 0x04 || x || y where x, y are curve_size_in_bytes big-endian byte array. |
| // The compressed point is encoded as 1-byte || x where x is |
| // curve_size_in_bytes big-endian byte array and if the least significant bit |
| // of y is 1, the 1st byte is 0x03, otherwise it's 0x02. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<internal::SslUniquePtr<EC_POINT>> |
| EcPointDecode(EllipticCurveType curve, EcPointFormat format, |
| absl::string_view encoded) { |
| return internal::EcPointDecode(curve, format, encoded); |
| } |
| |
| // Returns the encoded public key based on curve type, point format and |
| // BoringSSL's EC_POINT public key point. The uncompressed point is encoded as |
| // 0x04 || x || y where x, y are curve_size_in_bytes big-endian byte array. |
| // The compressed point is encoded as 1-byte || x where x is |
| // curve_size_in_bytes big-endian byte array and if the least significant bit |
| // of y is 1, the 1st byte is 0x03, otherwise it's 0x02. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<std::string> EcPointEncode( |
| EllipticCurveType curve, EcPointFormat format, const EC_POINT *point) { |
| return internal::EcPointEncode(curve, format, point); |
| } |
| |
| // Returns the ECDH's shared secret based on our private key and peer's public |
| // key. Returns error if the public key is not on private key's curve. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<util::SecretData> |
| ComputeEcdhSharedSecret(EllipticCurveType curve, const BIGNUM *priv_key, |
| const EC_POINT *pub_key) { |
| return internal::ComputeEcdhSharedSecret(curve, priv_key, pub_key); |
| } |
| |
| // Transforms ECDSA IEEE_P1363 signature encoding to DER encoding. |
| // |
| // The IEEE_P1363 signature's format is r || s, where r and s are zero-padded |
| // and have the same size in bytes as the order of the curve. For example, for |
| // NIST P-256 curve, r and s are zero-padded to 32 bytes. |
| // |
| // The DER signature is encoded using ASN.1 |
| // (https://tools.ietf.org/html/rfc5480#appendix-A): |
| // ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }. |
| // In particular, the encoding is: |
| // 0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<std::string> EcSignatureIeeeToDer( |
| const EC_GROUP *group, absl::string_view ieee_sig) { |
| return internal::EcSignatureIeeeToDer(group, ieee_sig); |
| } |
| |
| // Returns an EVP structure for a hash function. |
| // The EVP_MD instances are sigletons owned by BoringSSL. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::StatusOr<const EVP_MD *> EvpHash( |
| HashType hash_type) { |
| return internal::EvpHashFromHashType(hash_type); |
| } |
| |
| // Validates whether 'sig_hash' is safe to use for digital signature. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::Status ValidateSignatureHash( |
| subtle::HashType sig_hash) { |
| return internal::IsHashTypeSafeForSignature(sig_hash); |
| } |
| |
| // Return an empty string if str.data() is nullptr; otherwise return str. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline absl::string_view EnsureNonNull(absl::string_view str) { |
| return internal::EnsureStringNonNull(str); |
| } |
| |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::Status ValidateRsaModulusSize( |
| size_t modulus_size) { |
| return internal::ValidateRsaModulusSize(modulus_size); |
| } |
| |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline crypto::tink::util::Status ValidateRsaPublicExponent( |
| absl::string_view exponent) { |
| return internal::ValidateRsaPublicExponent(exponent); |
| } |
| |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::Status GetNewRsaKeyPair(int modulus_size_in_bits, |
| const BIGNUM *e, |
| RsaPrivateKey *private_key, |
| RsaPublicKey *public_key) { |
| return internal::NewRsaKeyPair(modulus_size_in_bits, e, private_key, |
| public_key); |
| } |
| |
| // Copies n, e and d into the RSA key. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::Status CopyKey(const RsaPrivateKey &key, RSA *rsa) { |
| return internal::GetRsaModAndExponents(key, rsa); |
| } |
| |
| // Copies the prime factors (p, q) into the RSA key. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::Status CopyPrimeFactors(const RsaPrivateKey &key, |
| RSA *rsa) { |
| return internal::GetRsaPrimeFactors(key, rsa); |
| } |
| |
| // Copies the CRT params and dp, dq into the RSA key. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::Status CopyCrtParams(const RsaPrivateKey &key, RSA *rsa) { |
| return internal::GetRsaCrtParams(key, rsa); |
| } |
| |
| // Creates a BoringSSL RSA key from an RsaPrivateKey. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::StatusOr<internal::SslUniquePtr<RSA>> |
| BoringSslRsaFromRsaPrivateKey(const RsaPrivateKey &key) { |
| return internal::RsaPrivateKeyToRsa(key); |
| } |
| |
| // Creates a BoringSSL RSA key from an RsaPublicKey. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline util::StatusOr<internal::SslUniquePtr<RSA>> |
| BoringSslRsaFromRsaPublicKey(const RsaPublicKey &key) { |
| return internal::RsaPublicKeyToRsa(key); |
| } |
| |
| // Returns BoringSSL's AES CTR EVP_CIPHER for the key size. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline const EVP_CIPHER *GetAesCtrCipherForKeySize( |
| uint32_t size_in_bytes) { |
| util::StatusOr<const EVP_CIPHER *> res = |
| internal::GetAesCtrCipherForKeySize(size_in_bytes); |
| if (!res.ok()) { |
| return nullptr; |
| } |
| return *res; |
| } |
| |
| // Returns BoringSSL's AES GCM EVP_CIPHER for the key size. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline const EVP_CIPHER *GetAesGcmCipherForKeySize( |
| uint32_t size_in_bytes) { |
| util::StatusOr<const EVP_CIPHER *> res = |
| internal::GetAesGcmCipherForKeySize(size_in_bytes); |
| if (!res.ok()) { |
| return nullptr; |
| } |
| return *res; |
| } |
| |
| #ifdef OPENSSL_IS_BORINGSSL |
| // Returns BoringSSL's AES GCM EVP_AEAD for the key size. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| static inline const EVP_AEAD *GetAesGcmAeadForKeySize( |
| uint32_t size_in_bytes) { |
| util::StatusOr<const EVP_AEAD *> res = |
| internal::GetAesGcmAeadForKeySize(size_in_bytes); |
| if (!res.ok()) { |
| return nullptr; |
| } |
| return *res; |
| } |
| #endif |
| }; |
| |
| namespace boringssl { |
| |
| // Computes hash of 'input' using the hash function 'hasher'. |
| ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.") |
| inline util::StatusOr<std::vector<uint8_t>> ComputeHash(absl::string_view input, |
| const EVP_MD &hasher) { |
| util::StatusOr<std::string> res = internal::ComputeHash(input, hasher); |
| if (!res.ok()) { |
| return res.status(); |
| } |
| return std::vector<uint8_t>(res->begin(), res->end()); |
| } |
| |
| } // namespace boringssl |
| } // namespace subtle |
| } // namespace tink |
| } // namespace crypto |
| |
| #endif // TINK_SUBTLE_SUBTLE_UTIL_BORINGSSL_H_ |