crypto: add obsolete/md5
Regrettably, there are many places in chromium where we use and need to continue using md5 hashes for compatibility with existing file formats or protocols. At the moment implementations of these use base/hash/md5, but the //base owners would very much like to kick that code out of //base. Therefore, this change adds a new md5 implementation as //crypto/obsolete/md5 and adds a large deprecation warning to the existing //base implementation. Using crypto/obsolete/md5 requires review by a CRYPTO_OWNERS member, and this is enforced using visibility rules. Bug: 406729261 Change-Id: I426dbd46aec358ef300d5f5a5bbb5adc881bc78b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6432267 Reviewed-by: Bob Beck <bbe@chromium.org> Commit-Queue: Elly FJ <ellyjones@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Cr-Commit-Position: refs/heads/main@{#1442511}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
1b8ebc2d9a
commit
35fe484d1d
@ -19,11 +19,19 @@
|
||||
#endif
|
||||
|
||||
// MD5 stands for Message Digest algorithm 5.
|
||||
// MD5 is a robust hash function, designed for cyptography, but often used
|
||||
// for file checksums. The code is complex and slow, but has few
|
||||
// collisions.
|
||||
// See Also:
|
||||
// http://en.wikipedia.org/wiki/MD5
|
||||
//
|
||||
// DANGER DANGER DANGER:
|
||||
// MD5 is extremely obsolete and it is trivial for a malicious party to find MD5
|
||||
// collisions. Do not use MD5 for any security-related purposes whatsoever, and
|
||||
// especially do not use MD5 to validate that files or other data have not been
|
||||
// modified maliciously. This entire interface is obsolete and you should either
|
||||
// use a non-cryptographic hash (which will be much faster) or a cryptographic
|
||||
// hash (which will be collision-resistant against adversarial inputs). If you
|
||||
// believe you need to add a new use of MD5, consult a member of
|
||||
// //CRYPTO_OWNERS.
|
||||
//
|
||||
// NEW USES OF THIS API ARE FORBIDDEN FOR ANY PURPOSE. INSTEAD, YOU MUST USE
|
||||
// //crypto/obsolete/md5.h.
|
||||
|
||||
// These functions perform MD5 operations. The simplest call is MD5Sum() to
|
||||
// generate the MD5 sum of the given data.
|
||||
|
@ -40,6 +40,8 @@ component("crypto") {
|
||||
"kdf.h",
|
||||
"keypair.cc",
|
||||
"keypair.h",
|
||||
"obsolete/md5.cc",
|
||||
"obsolete/md5.h",
|
||||
"openssl_util.cc",
|
||||
"openssl_util.h",
|
||||
"process_bound_string.cc",
|
||||
@ -183,6 +185,7 @@ test("crypto_unittests") {
|
||||
"hmac_unittest.cc",
|
||||
"kdf_unittest.cc",
|
||||
"keypair_unittest.cc",
|
||||
"obsolete/md5_unittest.cc",
|
||||
"process_bound_string_unittest.cc",
|
||||
"random_unittest.cc",
|
||||
"rsa_private_key_unittest.cc",
|
||||
|
12
crypto/obsolete/README.md
Normal file
12
crypto/obsolete/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# crypto/obsolete
|
||||
|
||||
This directory contains implementations of obsolete cryptographic primitives
|
||||
that we still need for compatibility with deployed protocols or file formats.
|
||||
All new uses of this code require approval by a `//CRYPTO_OWNERS` member. This
|
||||
requirement is enforced by requiring client code to be added to a friend list
|
||||
for the specific obsolete primitive that the client code wants to use, which
|
||||
has to be done by a crypto owner.
|
||||
|
||||
If you are designing a new protocol, or writing a new implementation, and
|
||||
believe you need to use one of these primitives, please contact a
|
||||
`//CRYPTO_OWNERS` member or security@chromium.org.
|
35
crypto/obsolete/md5.cc
Normal file
35
crypto/obsolete/md5.cc
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "crypto/obsolete/md5.h"
|
||||
|
||||
#include "third_party/boringssl/src/include/openssl/digest.h"
|
||||
#include "third_party/boringssl/src/include/openssl/evp.h"
|
||||
|
||||
namespace crypto::obsolete {
|
||||
|
||||
// static
|
||||
std::array<uint8_t, Md5::kSize> Md5::Hash(base::span<const uint8_t> data) {
|
||||
std::array<uint8_t, Md5::kSize> result;
|
||||
Md5 hasher;
|
||||
hasher.Update(data);
|
||||
hasher.Finish(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Md5::Md5() {
|
||||
CHECK(EVP_DigestInit(ctx_.get(), EVP_md5()));
|
||||
}
|
||||
|
||||
Md5::~Md5() = default;
|
||||
|
||||
void Md5::Update(base::span<const uint8_t> data) {
|
||||
CHECK(EVP_DigestUpdate(ctx_.get(), data.data(), data.size()));
|
||||
}
|
||||
|
||||
void Md5::Finish(base::span<uint8_t, Md5::kSize> result) {
|
||||
CHECK(EVP_DigestFinal(ctx_.get(), result.data(), nullptr));
|
||||
}
|
||||
|
||||
} // namespace crypto::obsolete
|
43
crypto/obsolete/md5.h
Normal file
43
crypto/obsolete/md5.h
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CRYPTO_OBSOLETE_MD5_H_
|
||||
#define CRYPTO_OBSOLETE_MD5_H_
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "crypto/crypto_export.h"
|
||||
#include "third_party/boringssl/src/include/openssl/evp.h"
|
||||
|
||||
namespace crypto::obsolete {
|
||||
|
||||
// This class is used for computing MD5 hashes, either one-shot via Md5::Hash(),
|
||||
// or streaming via constructing an Md5 instance, calling Update(), then calling
|
||||
// Finish(). It cannot be constructed except by friend classes, and to become a
|
||||
// friend class you must talk to a member of //CRYPTO_OWNERS. You should not use
|
||||
// MD5 in new production code.
|
||||
class CRYPTO_EXPORT Md5 {
|
||||
public:
|
||||
static constexpr size_t kSize = 16;
|
||||
|
||||
~Md5();
|
||||
|
||||
void Update(base::span<const uint8_t> data);
|
||||
|
||||
void Finish(base::span<uint8_t, kSize> result);
|
||||
|
||||
private:
|
||||
FRIEND_TEST_ALL_PREFIXES(Md5Test, KnownAnswer);
|
||||
|
||||
Md5();
|
||||
static std::array<uint8_t, kSize> Hash(base::span<const uint8_t> data);
|
||||
|
||||
bssl::ScopedEVP_MD_CTX ctx_;
|
||||
};
|
||||
|
||||
} // namespace crypto::obsolete
|
||||
|
||||
#endif // CRYPTO_OBSOLETE_MD5_H_
|
25
crypto/obsolete/md5_unittest.cc
Normal file
25
crypto/obsolete/md5_unittest.cc
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "crypto/obsolete/md5.h"
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
using Md5Test = ::testing::Test;
|
||||
|
||||
namespace crypto::obsolete {
|
||||
|
||||
TEST_F(Md5Test, KnownAnswer) {
|
||||
const std::string input = "The quick brown fox jumps over the lazy dog";
|
||||
// clang-format off
|
||||
constexpr auto expected = std::to_array<uint8_t>({
|
||||
0x9e, 0x10, 0x7d, 0x9d, 0x37, 0x2b, 0xb6, 0x82,
|
||||
0x6b, 0xd8, 0x1d, 0x35, 0x42, 0xa4, 0x19, 0xd6,
|
||||
});
|
||||
// clang-format on
|
||||
|
||||
EXPECT_EQ(expected, crypto::obsolete::Md5::Hash(base::as_byte_span(input)));
|
||||
}
|
||||
|
||||
} // namespace crypto::obsolete
|
Reference in New Issue
Block a user