xref: /aosp_15_r20/external/tink/cc/internal/md_util.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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