Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1059)

Unified Diff: content/child/webcrypto/openssl/pbkdf2_openssl.cc

Issue 797723006: Implement PBKDF2 (except for generateKey) using BoringSSL (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pbkdf2
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/child/webcrypto/nss/util_nss.cc ('k') | content/child/webcrypto/platform_crypto.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/webcrypto/openssl/pbkdf2_openssl.cc
diff --git a/content/child/webcrypto/openssl/hkdf_openssl.cc b/content/child/webcrypto/openssl/pbkdf2_openssl.cc
similarity index 56%
copy from content/child/webcrypto/openssl/hkdf_openssl.cc
copy to content/child/webcrypto/openssl/pbkdf2_openssl.cc
index 7a33b96e892accc351a501e165b9c1b4100ce544..e25d96cb4d2a54be7e16802f10dbb93d46244537 100644
--- a/content/child/webcrypto/openssl/hkdf_openssl.cc
+++ b/content/child/webcrypto/openssl/pbkdf2_openssl.cc
@@ -2,11 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <openssl/err.h>
-#include <openssl/hkdf.h>
-
-#include "base/logging.h"
-#include "base/stl_util.h"
+#include "base/numerics/safe_math.h"
#include "content/child/webcrypto/algorithm_implementation.h"
#include "content/child/webcrypto/crypto_data.h"
#include "content/child/webcrypto/openssl/key_openssl.h"
@@ -23,19 +19,22 @@ namespace webcrypto {
namespace {
-const blink::WebCryptoKeyUsageMask kValidUsages =
+const blink::WebCryptoKeyUsageMask kAllKeyUsages =
blink::WebCryptoKeyUsageDeriveKey | blink::WebCryptoKeyUsageDeriveBits;
-class HkdfImplementation : public AlgorithmImplementation {
+class Pbkdf2Implementation : public AlgorithmImplementation {
public:
- HkdfImplementation() {}
+ Pbkdf2Implementation() {}
Status VerifyKeyUsagesBeforeImportKey(
blink::WebCryptoKeyFormat format,
blink::WebCryptoKeyUsageMask usages) const override {
- if (format != blink::WebCryptoKeyFormatRaw)
- return Status::ErrorUnsupportedImportKeyFormat();
- return CheckKeyCreationUsages(kValidUsages, usages, false);
+ switch (format) {
+ case blink::WebCryptoKeyFormatRaw:
+ return CheckKeyCreationUsages(kAllKeyUsages, usages, false);
+ default:
+ return Status::ErrorUnsupportedImportKeyFormat();
+ }
}
Status ImportKeyRaw(const CryptoData& key_data,
@@ -43,10 +42,12 @@ class HkdfImplementation : public AlgorithmImplementation {
bool extractable,
blink::WebCryptoKeyUsageMask usages,
blink::WebCryptoKey* key) const override {
- return CreateWebCryptoSecretKey(
- key_data, blink::WebCryptoKeyAlgorithm::createWithoutParams(
- blink::WebCryptoAlgorithmIdHkdf),
- extractable, usages, key);
+ const blink::WebCryptoKeyAlgorithm key_algorithm =
+ blink::WebCryptoKeyAlgorithm::createWithoutParams(
+ blink::WebCryptoAlgorithmIdPbkdf2);
+
+ return CreateWebCryptoSecretKey(key_data, key_algorithm, extractable,
+ usages, key);
}
Status DeriveBits(const blink::WebCryptoAlgorithm& algorithm,
@@ -55,39 +56,51 @@ class HkdfImplementation : public AlgorithmImplementation {
unsigned int optional_length_bits,
std::vector<uint8_t>* derived_bytes) const override {
crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+
if (!has_optional_length_bits)
- return Status::ErrorHkdfDeriveBitsLengthNotSpecified();
+ return Status::ErrorPbkdf2DeriveBitsLengthNotSpecified();
- const blink::WebCryptoHkdfParams* params = algorithm.hkdfParams();
+ if (optional_length_bits % 8)
+ return Status::ErrorPbkdf2InvalidLength();
- const EVP_MD* digest_algorithm = GetDigest(params->hash().id());
+ const blink::WebCryptoPbkdf2Params* params = algorithm.pbkdf2Params();
+
+ const blink::WebCryptoAlgorithm& hash = params->hash();
+ const EVP_MD* digest_algorithm = GetDigest(hash.id());
if (!digest_algorithm)
return Status::ErrorUnsupported();
- // Size output to fit length
- unsigned int derived_bytes_len = NumBitsToBytes(optional_length_bits);
- derived_bytes->resize(derived_bytes_len);
+ unsigned int keylen_bytes = optional_length_bits / 8;
+ derived_bytes->resize(keylen_bytes);
- // Algorithm dispatch checks that the algorithm in |base_key| matches
- // |algorithm|.
- const std::vector<uint8_t>& raw_key =
+ const std::vector<uint8_t>& password =
SymKeyOpenSsl::Cast(base_key)->raw_key_data();
- const uint8_t* raw_key_ptr = raw_key.empty() ? NULL : &raw_key.front();
- uint8_t* derived_bytes_ptr =
- derived_bytes->empty() ? NULL : &derived_bytes->front();
- if (!HKDF(derived_bytes_ptr, derived_bytes_len, digest_algorithm,
- raw_key_ptr, raw_key.size(), params->salt().data(),
- params->salt().size(), params->info().data(),
- params->info().size())) {
- uint32_t error = ERR_get_error();
- if (ERR_GET_LIB(error) == ERR_LIB_HKDF &&
- ERR_GET_REASON(error) == HKDF_R_OUTPUT_TOO_LARGE) {
- return Status::ErrorHkdfLengthTooLong();
- }
- return Status::OperationError();
- }
- TruncateToBitLength(optional_length_bits, derived_bytes);
+ // TODO(xun.sun): Empty password would derive random keys with
+ // PKCS5_PBKDF2_HMAC().
+ // https://code.google.com/p/chromium/issues/detail?id=449409
+ //
+ // Rejecting them until it is addressed in BoringSSL.
+ if (password.empty())
+ return Status::ErrorPbkdf2EmptyPassword();
+
+ // Prevent underflowing password.size() - BoringSSL expects the size as an
+ // signed int, and will interpret the data as a C-String if it is -1.
+ base::CheckedNumeric<int> password_size = password.size();
+ if (!password_size.IsValid())
+ return Status::ErrorDataTooLarge();
+
+ if (keylen_bytes == 0)
+ return Status::Success();
+
+ const char* password_ptr =
+ password.empty() ? NULL : reinterpret_cast<const char*>(&password[0]);
+
+ if (!PKCS5_PBKDF2_HMAC(password_ptr, password_size.ValueOrDie(),
+ params->salt().data(), params->salt().size(),
+ params->iterations(), digest_algorithm, keylen_bytes,
+ &derived_bytes->front()))
+ return Status::OperationError();
return Status::Success();
}
@@ -118,8 +131,8 @@ class HkdfImplementation : public AlgorithmImplementation {
} // namespace
-AlgorithmImplementation* CreatePlatformHkdfImplementation() {
- return new HkdfImplementation;
+AlgorithmImplementation* CreatePlatformPbkdf2Implementation() {
+ return new Pbkdf2Implementation;
}
} // namespace webcrypto
« no previous file with comments | « content/child/webcrypto/nss/util_nss.cc ('k') | content/child/webcrypto/platform_crypto.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698