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_SUBTLE_UTIL_BORINGSSL_H_
18 #define TINK_SUBTLE_SUBTLE_UTIL_BORINGSSL_H_
19
20 #include <cstdint>
21 #include <memory>
22 #include <string>
23 #include <utility>
24 #include <vector>
25
26 #include "absl/base/attributes.h"
27 #include "absl/base/macros.h"
28 #include "absl/strings/string_view.h"
29 #include "openssl/bn.h"
30 #include "openssl/evp.h"
31 #include "tink/aead/internal/aead_util.h"
32 #include "tink/internal/aes_util.h"
33 #include "tink/internal/bn_util.h"
34 #include "tink/internal/ec_util.h"
35 #include "tink/internal/err_util.h"
36 #include "tink/internal/md_util.h"
37 #include "tink/internal/rsa_util.h"
38 #include "tink/internal/ssl_unique_ptr.h"
39 #include "tink/internal/util.h"
40 #include "tink/subtle/common_enums.h"
41 #include "tink/util/secret_data.h"
42 #include "tink/util/status.h"
43 #include "tink/util/statusor.h"
44
45 namespace crypto {
46 namespace tink {
47 namespace subtle {
48
49 class SubtleUtilBoringSSL {
50 public:
51 using EcKey ABSL_DEPRECATED("Use of this type is dicouraged outside Tink.") =
52 internal::EcKey;
53 using X25519Key ABSL_DEPRECATED(
54 "Use of this type is dicouraged outside Tink.") = internal::X25519Key;
55 using Ed25519Key ABSL_DEPRECATED(
56 "Use of this type is dicouraged outside Tink.") = internal::Ed25519Key;
57 using RsaPublicKey ABSL_DEPRECATED(
58 "Use of this type is dicouraged outside Tink.") = internal::RsaPublicKey;
59 using RsaSsaPssParams ABSL_DEPRECATED(
60 "Use of this type is dicouraged outside Tink.") =
61 internal::RsaSsaPssParams;
62 using RsaSsaPkcs1Params ABSL_DEPRECATED(
63 "Use of this type is dicouraged outside Tink.") =
64 internal::RsaSsaPkcs1Params;
65 using RsaPrivateKey ABSL_DEPRECATED(
66 "Use of this type is dicouraged outside Tink.") = internal::RsaPrivateKey;
67
68 // Returns BoringSSL's BIGNUM constructed from bigendian string
69 // representation.
70 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
str2bn(absl::string_view s)71 static inline util::StatusOr<internal::SslUniquePtr<BIGNUM>> str2bn(
72 absl::string_view s) {
73 return internal::StringToBignum(s);
74 }
75
76 // Returns a SecretData of size 'len' that holds BIGNUM 'bn'.
77 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
bn2str(const BIGNUM * bn,size_t len)78 static inline util::StatusOr<std::string> bn2str(const BIGNUM *bn,
79 size_t len) {
80 return internal::BignumToString(bn, len);
81 }
82
83 // Returns a string of size 'len' that holds BIGNUM 'bn'.
84 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
BignumToSecretData(const BIGNUM * bn,size_t len)85 static inline util::StatusOr<util::SecretData> BignumToSecretData(
86 const BIGNUM *bn, size_t len) {
87 return internal::BignumToSecretData(bn, len);
88 }
89
90 // Returns BoringSSL error strings accumulated in the error queue,
91 // thus emptying the queue.
92 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetErrors()93 static inline std::string GetErrors() { return internal::GetSslErrors(); }
94
95 // Returns BoringSSL's EC_GROUP constructed from the curve type.
96 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetEcGroup(EllipticCurveType curve_type)97 static inline crypto::tink::util::StatusOr<EC_GROUP *> GetEcGroup(
98 EllipticCurveType curve_type) {
99 util::StatusOr<internal::SslUniquePtr<EC_GROUP>> ec_group =
100 internal::EcGroupFromCurveType(curve_type);
101 if (!ec_group.ok()) {
102 return ec_group.status();
103 }
104 return ec_group->release();
105 }
106
107 // Returns the curve type associated with the EC_GROUP
108 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetCurve(const EC_GROUP * group)109 static inline crypto::tink::util::StatusOr<EllipticCurveType> GetCurve(
110 const EC_GROUP *group) {
111 return internal::CurveTypeFromEcGroup(group);
112 }
113
114 // Returns BoringSSL's EC_POINT constructed from the curve type, big-endian
115 // representation of public key's x-coordinate and y-coordinate.
116 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetEcPoint(EllipticCurveType curve,absl::string_view pubx,absl::string_view puby)117 static inline crypto::tink::util::StatusOr<EC_POINT *> GetEcPoint(
118 EllipticCurveType curve, absl::string_view pubx, absl::string_view puby) {
119 util::StatusOr<internal::SslUniquePtr<EC_POINT>> ec_point =
120 internal::GetEcPoint(curve, pubx, puby);
121 if (!ec_point.ok()) {
122 return ec_point.status();
123 }
124 return ec_point->release();
125 }
126
127 // Returns a new EC key for the specified curve.
128 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetNewEcKey(EllipticCurveType curve_type)129 static inline crypto::tink::util::StatusOr<EcKey> GetNewEcKey(
130 EllipticCurveType curve_type) {
131 return internal::NewEcKey(curve_type);
132 }
133
134 // Returns a new EC key for the specified curve derived from a seed.
135 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetNewEcKeyFromSeed(EllipticCurveType curve_type,const util::SecretData & secret_seed)136 static inline crypto::tink::util::StatusOr<EcKey> GetNewEcKeyFromSeed(
137 EllipticCurveType curve_type, const util::SecretData &secret_seed) {
138 return internal::NewEcKey(curve_type, secret_seed);
139 }
140
141 // Returns a new X25519 key, or nullptr if generation fails.
142 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GenerateNewX25519Key()143 static inline std::unique_ptr<X25519Key> GenerateNewX25519Key() {
144 util::StatusOr<std::unique_ptr<internal::X25519Key>> key =
145 internal::NewX25519Key();
146 if (!key.ok()) {
147 return nullptr;
148 }
149 return *std::move(key);
150 }
151
152 // Returns a X25519Key matching the specified EcKey.
153 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
154 static inline crypto::tink::util::StatusOr<std::unique_ptr<X25519Key>>
X25519KeyFromEcKey(const EcKey & ec_key)155 X25519KeyFromEcKey(const EcKey &ec_key) {
156 return internal::X25519KeyFromEcKey(ec_key);
157 }
158
159 // Returns an EcKey matching the specified X25519Key.
160 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
EcKeyFromX25519Key(const X25519Key * x25519_key)161 static inline EcKey EcKeyFromX25519Key(const X25519Key *x25519_key) {
162 return internal::EcKeyFromX25519Key(x25519_key);
163 }
164
165 // Returns a new ED25519 key.
166 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetNewEd25519Key()167 static inline std::unique_ptr<Ed25519Key> GetNewEd25519Key() {
168 util::StatusOr<std::unique_ptr<Ed25519Key>> key = internal::NewEd25519Key();
169 if (!key.ok()) {
170 return nullptr;
171 }
172 return *std::move(key);
173 }
174
175 // Returns a new ED25519 key generated from a 32-byte secret seed.
176 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetNewEd25519KeyFromSeed(const util::SecretData & secret_seed)177 static inline std::unique_ptr<Ed25519Key> GetNewEd25519KeyFromSeed(
178 const util::SecretData &secret_seed) {
179 util::StatusOr<std::unique_ptr<Ed25519Key>> key =
180 internal::NewEd25519Key(secret_seed);
181 if (!key.ok()) {
182 return nullptr;
183 }
184 return *std::move(key);
185 }
186
187 // Returns BoringSSL's EC_POINT constructed from curve type, point format and
188 // encoded public key's point. The uncompressed point is encoded as
189 // 0x04 || x || y where x, y are curve_size_in_bytes big-endian byte array.
190 // The compressed point is encoded as 1-byte || x where x is
191 // curve_size_in_bytes big-endian byte array and if the least significant bit
192 // of y is 1, the 1st byte is 0x03, otherwise it's 0x02.
193 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
194 static inline crypto::tink::util::StatusOr<internal::SslUniquePtr<EC_POINT>>
EcPointDecode(EllipticCurveType curve,EcPointFormat format,absl::string_view encoded)195 EcPointDecode(EllipticCurveType curve, EcPointFormat format,
196 absl::string_view encoded) {
197 return internal::EcPointDecode(curve, format, encoded);
198 }
199
200 // Returns the encoded public key based on curve type, point format and
201 // BoringSSL's EC_POINT public key point. The uncompressed point is encoded as
202 // 0x04 || x || y where x, y are curve_size_in_bytes big-endian byte array.
203 // The compressed point is encoded as 1-byte || x where x is
204 // curve_size_in_bytes big-endian byte array and if the least significant bit
205 // of y is 1, the 1st byte is 0x03, otherwise it's 0x02.
206 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
EcPointEncode(EllipticCurveType curve,EcPointFormat format,const EC_POINT * point)207 static inline crypto::tink::util::StatusOr<std::string> EcPointEncode(
208 EllipticCurveType curve, EcPointFormat format, const EC_POINT *point) {
209 return internal::EcPointEncode(curve, format, point);
210 }
211
212 // Returns the ECDH's shared secret based on our private key and peer's public
213 // key. Returns error if the public key is not on private key's curve.
214 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
215 static inline crypto::tink::util::StatusOr<util::SecretData>
ComputeEcdhSharedSecret(EllipticCurveType curve,const BIGNUM * priv_key,const EC_POINT * pub_key)216 ComputeEcdhSharedSecret(EllipticCurveType curve, const BIGNUM *priv_key,
217 const EC_POINT *pub_key) {
218 return internal::ComputeEcdhSharedSecret(curve, priv_key, pub_key);
219 }
220
221 // Transforms ECDSA IEEE_P1363 signature encoding to DER encoding.
222 //
223 // The IEEE_P1363 signature's format is r || s, where r and s are zero-padded
224 // and have the same size in bytes as the order of the curve. For example, for
225 // NIST P-256 curve, r and s are zero-padded to 32 bytes.
226 //
227 // The DER signature is encoded using ASN.1
228 // (https://tools.ietf.org/html/rfc5480#appendix-A):
229 // ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }.
230 // In particular, the encoding is:
231 // 0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s
232 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
EcSignatureIeeeToDer(const EC_GROUP * group,absl::string_view ieee_sig)233 static inline crypto::tink::util::StatusOr<std::string> EcSignatureIeeeToDer(
234 const EC_GROUP *group, absl::string_view ieee_sig) {
235 return internal::EcSignatureIeeeToDer(group, ieee_sig);
236 }
237
238 // Returns an EVP structure for a hash function.
239 // The EVP_MD instances are sigletons owned by BoringSSL.
240 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
EvpHash(HashType hash_type)241 static inline crypto::tink::util::StatusOr<const EVP_MD *> EvpHash(
242 HashType hash_type) {
243 return internal::EvpHashFromHashType(hash_type);
244 }
245
246 // Validates whether 'sig_hash' is safe to use for digital signature.
247 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
ValidateSignatureHash(subtle::HashType sig_hash)248 static inline crypto::tink::util::Status ValidateSignatureHash(
249 subtle::HashType sig_hash) {
250 return internal::IsHashTypeSafeForSignature(sig_hash);
251 }
252
253 // Return an empty string if str.data() is nullptr; otherwise return str.
254 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
EnsureNonNull(absl::string_view str)255 static inline absl::string_view EnsureNonNull(absl::string_view str) {
256 return internal::EnsureStringNonNull(str);
257 }
258
259 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
ValidateRsaModulusSize(size_t modulus_size)260 static inline crypto::tink::util::Status ValidateRsaModulusSize(
261 size_t modulus_size) {
262 return internal::ValidateRsaModulusSize(modulus_size);
263 }
264
265 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
ValidateRsaPublicExponent(absl::string_view exponent)266 static inline crypto::tink::util::Status ValidateRsaPublicExponent(
267 absl::string_view exponent) {
268 return internal::ValidateRsaPublicExponent(exponent);
269 }
270
271 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetNewRsaKeyPair(int modulus_size_in_bits,const BIGNUM * e,RsaPrivateKey * private_key,RsaPublicKey * public_key)272 static inline util::Status GetNewRsaKeyPair(int modulus_size_in_bits,
273 const BIGNUM *e,
274 RsaPrivateKey *private_key,
275 RsaPublicKey *public_key) {
276 return internal::NewRsaKeyPair(modulus_size_in_bits, e, private_key,
277 public_key);
278 }
279
280 // Copies n, e and d into the RSA key.
281 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
CopyKey(const RsaPrivateKey & key,RSA * rsa)282 static inline util::Status CopyKey(const RsaPrivateKey &key, RSA *rsa) {
283 return internal::GetRsaModAndExponents(key, rsa);
284 }
285
286 // Copies the prime factors (p, q) into the RSA key.
287 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
CopyPrimeFactors(const RsaPrivateKey & key,RSA * rsa)288 static inline util::Status CopyPrimeFactors(const RsaPrivateKey &key,
289 RSA *rsa) {
290 return internal::GetRsaPrimeFactors(key, rsa);
291 }
292
293 // Copies the CRT params and dp, dq into the RSA key.
294 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
CopyCrtParams(const RsaPrivateKey & key,RSA * rsa)295 static inline util::Status CopyCrtParams(const RsaPrivateKey &key, RSA *rsa) {
296 return internal::GetRsaCrtParams(key, rsa);
297 }
298
299 // Creates a BoringSSL RSA key from an RsaPrivateKey.
300 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
301 static inline util::StatusOr<internal::SslUniquePtr<RSA>>
BoringSslRsaFromRsaPrivateKey(const RsaPrivateKey & key)302 BoringSslRsaFromRsaPrivateKey(const RsaPrivateKey &key) {
303 return internal::RsaPrivateKeyToRsa(key);
304 }
305
306 // Creates a BoringSSL RSA key from an RsaPublicKey.
307 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
308 static inline util::StatusOr<internal::SslUniquePtr<RSA>>
BoringSslRsaFromRsaPublicKey(const RsaPublicKey & key)309 BoringSslRsaFromRsaPublicKey(const RsaPublicKey &key) {
310 return internal::RsaPublicKeyToRsa(key);
311 }
312
313 // Returns BoringSSL's AES CTR EVP_CIPHER for the key size.
314 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetAesCtrCipherForKeySize(uint32_t size_in_bytes)315 static inline const EVP_CIPHER *GetAesCtrCipherForKeySize(
316 uint32_t size_in_bytes) {
317 util::StatusOr<const EVP_CIPHER *> res =
318 internal::GetAesCtrCipherForKeySize(size_in_bytes);
319 if (!res.ok()) {
320 return nullptr;
321 }
322 return *res;
323 }
324
325 // Returns BoringSSL's AES GCM EVP_CIPHER for the key size.
326 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetAesGcmCipherForKeySize(uint32_t size_in_bytes)327 static inline const EVP_CIPHER *GetAesGcmCipherForKeySize(
328 uint32_t size_in_bytes) {
329 util::StatusOr<const EVP_CIPHER *> res =
330 internal::GetAesGcmCipherForKeySize(size_in_bytes);
331 if (!res.ok()) {
332 return nullptr;
333 }
334 return *res;
335 }
336
337 #ifdef OPENSSL_IS_BORINGSSL
338 // Returns BoringSSL's AES GCM EVP_AEAD for the key size.
339 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
GetAesGcmAeadForKeySize(uint32_t size_in_bytes)340 static inline const EVP_AEAD *GetAesGcmAeadForKeySize(
341 uint32_t size_in_bytes) {
342 util::StatusOr<const EVP_AEAD *> res =
343 internal::GetAesGcmAeadForKeySize(size_in_bytes);
344 if (!res.ok()) {
345 return nullptr;
346 }
347 return *res;
348 }
349 #endif
350 };
351
352 namespace boringssl {
353
354 // Computes hash of 'input' using the hash function 'hasher'.
355 ABSL_DEPRECATED("Use of this function is dicouraged outside Tink.")
ComputeHash(absl::string_view input,const EVP_MD & hasher)356 inline util::StatusOr<std::vector<uint8_t>> ComputeHash(absl::string_view input,
357 const EVP_MD &hasher) {
358 util::StatusOr<std::string> res = internal::ComputeHash(input, hasher);
359 if (!res.ok()) {
360 return res.status();
361 }
362 return std::vector<uint8_t>(res->begin(), res->end());
363 }
364
365 } // namespace boringssl
366 } // namespace subtle
367 } // namespace tink
368 } // namespace crypto
369
370 #endif // TINK_SUBTLE_SUBTLE_UTIL_BORINGSSL_H_
371