Update Simulcrypt ECMg
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "openssl/sha.h"
|
||||
#include "common/aes_cbc_util.h"
|
||||
#include "common/ec_util.h"
|
||||
#include "common/hash_algorithm.h"
|
||||
#include "common/openssl_util.h"
|
||||
#include "common/sha_util.h"
|
||||
|
||||
@@ -53,6 +54,22 @@ std::string OpenSSLErrorString(uint32_t error) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string GetMessageDigest(const std::string& message,
|
||||
widevine::HashAlgorithm hash_algorithm) {
|
||||
switch (hash_algorithm) {
|
||||
case widevine::HashAlgorithm::kUnspecified:
|
||||
case widevine::HashAlgorithm::kSha256:
|
||||
return widevine::Sha256_Hash(message);
|
||||
case widevine::HashAlgorithm::kSha1:
|
||||
LOG(ERROR) << "Unexpected hash algorithm: "
|
||||
<< static_cast<int>(hash_algorithm);
|
||||
return "";
|
||||
}
|
||||
LOG(FATAL) << "Unexpected hash algorithm: "
|
||||
<< static_cast<int>(hash_algorithm);
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ECPrivateKey::ECPrivateKey(EC_KEY* ec_key) : key_(ec_key) {
|
||||
@@ -159,6 +176,47 @@ bool ECPrivateKey::GenerateSignature(const std::string& message,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ECPrivateKey::GenerateSignature(const std::string& message,
|
||||
HashAlgorithm hash_algorithm,
|
||||
std::string* signature) const {
|
||||
if (message.empty()) {
|
||||
LOG(ERROR) << "|message| cannot be empty";
|
||||
return false;
|
||||
}
|
||||
if (signature == nullptr) {
|
||||
LOG(ERROR) << "|signature| cannot be nullptr";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hash the message using corresponding hash algorithm.
|
||||
std::string message_digest = GetMessageDigest(message, hash_algorithm);
|
||||
if (message_digest.empty()) {
|
||||
LOG(ERROR) << "Empty message digest";
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t max_signature_size = ECDSA_size(key());
|
||||
if (max_signature_size == 0) {
|
||||
LOG(ERROR) << "key_ does not have a group set";
|
||||
return false;
|
||||
}
|
||||
signature->resize(max_signature_size);
|
||||
unsigned int bytes_written = 0;
|
||||
int result = ECDSA_sign(
|
||||
0 /* unused type */,
|
||||
reinterpret_cast<const uint8_t*>(message_digest.data()),
|
||||
message_digest.size(),
|
||||
reinterpret_cast<uint8_t*>(const_cast<char*>(signature->data())),
|
||||
&bytes_written, key());
|
||||
if (result != 1) {
|
||||
LOG(ERROR) << "Could not calculate signature: "
|
||||
<< OpenSSLErrorString(ERR_get_error());
|
||||
return false;
|
||||
}
|
||||
signature->resize(bytes_written);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ECPrivateKey::MatchesPrivateKey(const ECPrivateKey& private_key) const {
|
||||
return BN_cmp(EC_KEY_get0_private_key(key()),
|
||||
EC_KEY_get0_private_key(private_key.key())) == 0;
|
||||
@@ -254,6 +312,39 @@ bool ECPublicKey::VerifySignature(const std::string& message,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ECPublicKey::VerifySignature(const std::string& message,
|
||||
HashAlgorithm hash_algorithm,
|
||||
const std::string& signature) const {
|
||||
if (message.empty()) {
|
||||
LOG(ERROR) << "|message| cannot be empty";
|
||||
return false;
|
||||
}
|
||||
if (signature.empty()) {
|
||||
LOG(ERROR) << "|signature| cannot be empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hash the message using corresponding hash algorithm.
|
||||
std::string message_digest = GetMessageDigest(message, hash_algorithm);
|
||||
if (message_digest.empty()) {
|
||||
LOG(ERROR) << "Empty message digest";
|
||||
return false;
|
||||
}
|
||||
|
||||
int result = ECDSA_verify(
|
||||
0 /* unused type */,
|
||||
reinterpret_cast<const uint8_t*>(message_digest.data()),
|
||||
message_digest.size(),
|
||||
reinterpret_cast<uint8_t*>(const_cast<char*>(signature.data())),
|
||||
signature.size(), key());
|
||||
if (result != 1) {
|
||||
LOG(ERROR) << "Could not verify signature: "
|
||||
<< OpenSSLErrorString(ERR_get_error());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ECPublicKey::MatchesPrivateKey(const ECPrivateKey& private_key) const {
|
||||
return private_key.MatchesPublicKey(*this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user