Chromium Code Reviews| Index: crypto/encryptor.cc |
| diff --git a/crypto/encryptor.cc b/crypto/encryptor.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8dbb8350067990e70a55db82f0acb9ec3d7f7da5 |
| --- /dev/null |
| +++ b/crypto/encryptor.cc |
| @@ -0,0 +1,127 @@ |
| +// Copyright (c) 2011 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 "crypto/encryptor.h" |
| + |
| +#include "base/logging.h" |
| + |
| +namespace crypto { |
| + |
| +namespace { |
| + |
| +const size_t kCounterLength = 16u; |
| + |
| +inline void Set8(void* memory, size_t offset, uint8 v) { |
| + static_cast<uint8*>(memory)[offset] = v; |
| +} |
| + |
| +inline uint8 Get8(const void* memory, size_t offset) { |
| + return static_cast<const uint8*>(memory)[offset]; |
| +} |
| + |
| +inline void SetBE64(void* memory, uint64 v) { |
| + Set8(memory, 0, static_cast<uint8>(v >> 56)); |
| + Set8(memory, 1, static_cast<uint8>(v >> 48)); |
| + Set8(memory, 2, static_cast<uint8>(v >> 40)); |
| + Set8(memory, 3, static_cast<uint8>(v >> 32)); |
| + Set8(memory, 4, static_cast<uint8>(v >> 24)); |
| + Set8(memory, 5, static_cast<uint8>(v >> 16)); |
| + Set8(memory, 6, static_cast<uint8>(v >> 8)); |
| + Set8(memory, 7, static_cast<uint8>(v >> 0)); |
| +} |
| + |
| +inline uint64 GetBE64(const void* memory) { |
| + return (static_cast<uint64>(Get8(memory, 0)) << 56) | |
| + (static_cast<uint64>(Get8(memory, 1)) << 48) | |
| + (static_cast<uint64>(Get8(memory, 2)) << 40) | |
| + (static_cast<uint64>(Get8(memory, 3)) << 32) | |
| + (static_cast<uint64>(Get8(memory, 4)) << 24) | |
| + (static_cast<uint64>(Get8(memory, 5)) << 16) | |
| + (static_cast<uint64>(Get8(memory, 6)) << 8) | |
| + (static_cast<uint64>(Get8(memory, 7)) << 0); |
| +} |
|
wtc
2011/06/21 00:46:32
There are compiler built-in or intrinsic functions
Alpha Left Google
2011/06/22 21:25:17
Done.
|
| + |
| +} // namespace |
| + |
| +///////////////////////////////////////////////////////////////////////////// |
| +// Encyptor::Counter Implementation. |
| +Encryptor::Counter::Counter(const std::string& counter) { |
| + CHECK_EQ(kCounterLength, counter.length()); |
| + |
| + high_num_ = GetBE64(counter.data()); |
| + low_num_ = GetBE64(counter.data() + sizeof(high_num_)); |
| +} |
| + |
| +Encryptor::Counter::~Counter() { |
| +} |
| + |
| +void Encryptor::Counter::Increment() { |
| + uint64 old_num = low_num_; |
| + ++low_num_; |
| + |
| + // Overflow occurs. |
| + if (low_num_ < old_num) |
| + ++high_num_; |
| +} |
| + |
| +void Encryptor::Counter::Write(void* buf) { |
| + uint8* buf_ptr = reinterpret_cast<uint8*>(buf); |
| + |
| + SetBE64(buf_ptr, high_num_); |
| + SetBE64(buf_ptr + sizeof(high_num_), low_num_); |
| +} |
| + |
| +size_t Encryptor::Counter::GetLengthInBytes() const { |
| + return kCounterLength; |
| +} |
| + |
| +///////////////////////////////////////////////////////////////////////////// |
| +// Partial Encryptor Implementation. |
| + |
| +bool Encryptor::UpdateCounter(const std::string& counter) { |
| + if (mode_ != CTR) |
| + return false; |
| + if (counter.length() != kCounterLength) |
| + return false; |
| + |
| + counter_.reset(new Counter(counter)); |
| + return true; |
| +} |
| + |
| +void Encryptor::GenerateCounterMask(size_t plaintext_len, |
| + scoped_array<uint8>* mask, |
| + size_t* mask_len) { |
| + DCHECK_EQ(CTR, mode_); |
| + CHECK(mask); |
| + CHECK(mask_len); |
| + |
| + const size_t kBlockLength = counter_->GetLengthInBytes(); |
| + size_t blocks = (plaintext_len + kBlockLength - 1) / kBlockLength; |
| + CHECK(blocks); |
| + |
| + *mask_len = blocks * kBlockLength; |
| + mask->reset(new uint8[*mask_len]); |
| + |
| + uint8* buf = mask->get(); |
| + for (size_t i = 0; i < blocks; ++i) { |
| + counter_->Write(buf); |
| + buf += kBlockLength; |
| + counter_->Increment(); |
| + } |
| +} |
| + |
| +void Encryptor::MaskMessage(const void* plaintext, |
| + size_t plaintext_len, |
| + const void* mask, |
| + void* ciphertext) const { |
| + DCHECK_EQ(CTR, mode_); |
| + const uint8* plaintext_ptr = reinterpret_cast<const uint8*>(plaintext); |
| + const uint8* mask_ptr = reinterpret_cast<const uint8*>(mask); |
| + uint8* ciphertext_ptr = reinterpret_cast<uint8*>(ciphertext); |
| + |
| + for (size_t i = 0; i < plaintext_len; ++i) |
| + ciphertext_ptr[i] = plaintext_ptr[i] ^ mask_ptr[i]; |
| +} |
| + |
| +} // namespace crypto |