blob: 4339aa2751129321b586933ebf02407915465f8f [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/nearby_sharing/certificates/common.h"
#include "base/logging.h"
#include "base/rand_util.h"
#include "chrome/browser/nearby_sharing/certificates/constants.h"
#include "crypto/encryptor.h"
#include "crypto/hkdf.h"
#include "crypto/random.h"
#include "crypto/sha2.h"
#include "crypto/symmetric_key.h"
bool IsNearbyShareCertificateExpired(base::Time current_time,
base::Time not_after,
bool use_public_certificate_tolerance) {
base::TimeDelta tolerance =
use_public_certificate_tolerance
? kNearbySharePublicCertificateValidityBoundOffsetTolerance
: base::Seconds(0);
return current_time >= not_after + tolerance;
}
bool IsNearbyShareCertificateWithinValidityPeriod(
base::Time current_time,
base::Time not_before,
base::Time not_after,
bool use_public_certificate_tolerance) {
base::TimeDelta tolerance =
use_public_certificate_tolerance
? kNearbySharePublicCertificateValidityBoundOffsetTolerance
: base::Seconds(0);
return current_time >= not_before - tolerance &&
!IsNearbyShareCertificateExpired(current_time, not_after,
use_public_certificate_tolerance);
}
std::vector<uint8_t> DeriveNearbyShareKey(base::span<const uint8_t> key,
size_t new_num_bytes) {
return crypto::HkdfSha256(key,
/*salt=*/base::span<const uint8_t>(),
/*info=*/base::span<const uint8_t>(),
new_num_bytes);
}
std::vector<uint8_t> ComputeAuthenticationTokenHash(
base::span<const uint8_t> authentication_token,
base::span<const uint8_t> secret_key) {
return crypto::HkdfSha256(authentication_token, secret_key,
/*info=*/base::span<const uint8_t>(),
kNearbyShareNumBytesAuthenticationTokenHash);
}
std::vector<uint8_t> GenerateRandomBytes(size_t num_bytes) {
std::vector<uint8_t> bytes(num_bytes);
crypto::RandBytes(bytes);
return bytes;
}
std::unique_ptr<crypto::Encryptor> CreateNearbyShareCtrEncryptor(
const crypto::SymmetricKey* secret_key,
base::span<const uint8_t> salt) {
DCHECK(secret_key);
DCHECK_EQ(kNearbyShareNumBytesSecretKey, secret_key->key().size());
DCHECK_EQ(kNearbyShareNumBytesMetadataEncryptionKeySalt, salt.size());
std::unique_ptr<crypto::Encryptor> encryptor =
std::make_unique<crypto::Encryptor>();
// For CTR mode, the iv input to Init() must be empty. Instead, the iv is
// set via SetCounter().
if (!encryptor->Init(secret_key, crypto::Encryptor::Mode::CTR,
/*iv=*/base::span<const uint8_t>())) {
LOG(ERROR) << "Encryptor could not be initialized.";
return nullptr;
}
std::vector<uint8_t> iv =
DeriveNearbyShareKey(salt, kNearbyShareNumBytesAesCtrIv);
if (!encryptor->SetCounter(iv)) {
LOG(ERROR) << "Could not set encryptor counter.";
return nullptr;
}
return encryptor;
}