// 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 #include #include #include #include #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> 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 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 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 GetEcGroup( EllipticCurveType curve_type) { util::StatusOr> 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 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 GetEcPoint( EllipticCurveType curve, absl::string_view pubx, absl::string_view puby) { util::StatusOr> 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 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 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 GenerateNewX25519Key() { util::StatusOr> 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> 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 GetNewEd25519Key() { util::StatusOr> 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 GetNewEd25519KeyFromSeed( const util::SecretData &secret_seed) { util::StatusOr> 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> 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 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 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 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 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> 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> 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 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 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 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> ComputeHash(absl::string_view input, const EVP_MD &hasher) { util::StatusOr res = internal::ComputeHash(input, hasher); if (!res.ok()) { return res.status(); } return std::vector(res->begin(), res->end()); } } // namespace boringssl } // namespace subtle } // namespace tink } // namespace crypto #endif // TINK_SUBTLE_SUBTLE_UTIL_BORINGSSL_H_