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 #include "tink/subtle/ecdsa_sign_boringssl.h"
18
19 #include <memory>
20 #include <string>
21 #include <utility>
22 #include <vector>
23
24 #include "absl/status/status.h"
25 #include "openssl/evp.h"
26 #include "tink/internal/md_util.h"
27 #include "tink/internal/util.h"
28 #include "tink/signature/internal/ecdsa_raw_sign_boringssl.h"
29 #include "tink/subtle/common_enums.h"
30 #include "tink/subtle/subtle_util_boringssl.h"
31 #include "tink/util/statusor.h"
32
33 namespace crypto {
34 namespace tink {
35 namespace subtle {
36
New(const SubtleUtilBoringSSL::EcKey & ec_key,HashType hash_type,EcdsaSignatureEncoding encoding)37 util::StatusOr<std::unique_ptr<EcdsaSignBoringSsl>> EcdsaSignBoringSsl::New(
38 const SubtleUtilBoringSSL::EcKey& ec_key, HashType hash_type,
39 EcdsaSignatureEncoding encoding) {
40 auto status = internal::CheckFipsCompatibility<EcdsaSignBoringSsl>();
41 if (!status.ok()) return status;
42
43 // Check if the hash type is safe to use.
44 util::Status is_safe = internal::IsHashTypeSafeForSignature(hash_type);
45 if (!is_safe.ok()) {
46 return is_safe;
47 }
48 util::StatusOr<const EVP_MD*> hash = internal::EvpHashFromHashType(hash_type);
49 if (!hash.ok()) {
50 return hash.status();
51 }
52
53 util::StatusOr<std::unique_ptr<internal::EcdsaRawSignBoringSsl>> raw_sign =
54 internal::EcdsaRawSignBoringSsl::New(ec_key, encoding);
55 if (!raw_sign.ok()) return raw_sign.status();
56
57 return {
58 absl::WrapUnique(new EcdsaSignBoringSsl(*hash, std::move(*raw_sign)))};
59 }
60
Sign(absl::string_view data) const61 util::StatusOr<std::string> EcdsaSignBoringSsl::Sign(
62 absl::string_view data) const {
63 // BoringSSL expects a non-null pointer for data,
64 // regardless of whether the size is 0.
65 data = internal::EnsureStringNonNull(data);
66
67 // Compute the digest.
68 unsigned int digest_size;
69 uint8_t digest[EVP_MAX_MD_SIZE];
70 if (1 != EVP_Digest(data.data(), data.size(), digest, &digest_size, hash_,
71 nullptr)) {
72 return util::Status(absl::StatusCode::kInternal,
73 "Could not compute digest.");
74 }
75
76 // Compute the signature.
77 return raw_signer_->Sign(
78 absl::string_view(reinterpret_cast<char*>(digest), digest_size));
79 }
80
81 } // namespace subtle
82 } // namespace tink
83 } // namespace crypto
84