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); |
+} |
+ |
+} // 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. |
wtc
2011/06/21 00:33:32
Nit: perhaps past tense ("occurred") would be bett
Alpha Left Google
2011/06/22 21:25:17
Done.
|
+ 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]); |
wtc
2011/06/21 00:33:32
It is inefficient to allocate the mask block in ev
|
+ |
+ 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 |