1 // Copyright 2021 Google LLC
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 #include "tink/internal/md_util.h"
17
18 #include <stdint.h>
19
20 #include <string>
21
22 #include "absl/status/status.h"
23 #include "absl/strings/str_cat.h"
24 #include "absl/strings/string_view.h"
25 #include "openssl/evp.h"
26 #include "tink/internal/err_util.h"
27 #include "tink/internal/util.h"
28 #include "tink/subtle/common_enums.h"
29 #include "tink/subtle/subtle_util.h"
30 #include "tink/util/status.h"
31 #include "tink/util/statusor.h"
32
33 namespace crypto {
34 namespace tink {
35 namespace internal {
36
EvpHashFromHashType(subtle::HashType hash_type)37 util::StatusOr<const EVP_MD *> EvpHashFromHashType(subtle::HashType hash_type) {
38 switch (hash_type) {
39 case subtle::HashType::SHA1:
40 return EVP_sha1();
41 case subtle::HashType::SHA224:
42 return EVP_sha224();
43 case subtle::HashType::SHA256:
44 return EVP_sha256();
45 case subtle::HashType::SHA384:
46 return EVP_sha384();
47 case subtle::HashType::SHA512:
48 return EVP_sha512();
49 default:
50 return util::Status(
51 absl::StatusCode::kUnimplemented,
52 absl::StrCat("Unsupported hash ", subtle::EnumToString(hash_type)));
53 }
54 }
55
IsHashTypeSafeForSignature(subtle::HashType sig_hash)56 util::Status IsHashTypeSafeForSignature(subtle::HashType sig_hash) {
57 switch (sig_hash) {
58 case subtle::HashType::SHA256:
59 case subtle::HashType::SHA384:
60 case subtle::HashType::SHA512:
61 return util::OkStatus();
62 case subtle::HashType::SHA1:
63 case subtle::HashType::SHA224:
64 return util::Status(
65 absl::StatusCode::kInvalidArgument,
66 absl::StrCat("Hash function ", subtle::EnumToString(sig_hash),
67 " is not safe for digital signature"));
68 default:
69 return util::Status(absl::StatusCode::kInvalidArgument,
70 "Unsupported hash function");
71 }
72 }
73
ComputeHash(absl::string_view input,const EVP_MD & hasher)74 util::StatusOr<std::string> ComputeHash(absl::string_view input,
75 const EVP_MD &hasher) {
76 input = EnsureStringNonNull(input);
77 std::string digest;
78 subtle::ResizeStringUninitialized(&digest, EVP_MAX_MD_SIZE);
79 uint32_t digest_length = 0;
80 if (EVP_Digest(input.data(), input.length(),
81 reinterpret_cast<uint8_t *>(&digest[0]), &digest_length,
82 &hasher, /*impl=*/nullptr) != 1) {
83 return util::Status(absl::StatusCode::kInternal,
84 absl::StrCat("Openssl internal error computing hash: ",
85 internal::GetSslErrors()));
86 }
87 digest.resize(digest_length);
88 return digest;
89 }
90
91 } // namespace internal
92 } // namespace tink
93 } // namespace crypto
94