| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef COMPONENTS_AUTOFILL_BROWSER_CRYPTO_RC4_DECRYPTOR_H_ | |
| 6 #define COMPONENTS_AUTOFILL_BROWSER_CRYPTO_RC4_DECRYPTOR_H_ | |
| 7 | |
| 8 #include <string> | |
| 9 #include "base/basictypes.h" | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 | |
| 12 namespace autofill { | |
| 13 | |
| 14 // This is modified RC4 decryption used for import of Toolbar autofill data | |
| 15 // only. The difference from the Crypto Api implementation is twofold: | |
| 16 // First, it uses a non-standard key size (160 bit), not supported by Microsoft | |
| 17 // (it supports only 40 and 128 bit for RC4). Second, it codes 128 words with | |
| 18 // value 0x0020 at the beginning of the code to enhance security. | |
| 19 // | |
| 20 // This class used in | |
| 21 // components/autofill/browser/autofill_ie_toolbar_import_win.cc. | |
| 22 // | |
| 23 // This class should not be used anywhere else!!! | |
| 24 class RC4Decryptor { | |
| 25 public: | |
| 26 explicit RC4Decryptor(wchar_t const* password) { | |
| 27 PrepareKey(reinterpret_cast<const uint8 *>(password), | |
| 28 wcslen(password) * sizeof(wchar_t)); | |
| 29 std::wstring data; | |
| 30 // First 128 bytes should be spaces. | |
| 31 data.resize(128, L' '); | |
| 32 Run(data.c_str()); | |
| 33 } | |
| 34 | |
| 35 // Run the algorithm | |
| 36 std::wstring Run(const std::wstring& data) { | |
| 37 int data_size = data.length() * sizeof(wchar_t); | |
| 38 | |
| 39 scoped_ptr<wchar_t[]> buffer(new wchar_t[data.length() + 1]); | |
| 40 memset(buffer.get(), 0, (data.length() + 1) * sizeof(wchar_t)); | |
| 41 memcpy(buffer.get(), data.c_str(), data_size); | |
| 42 | |
| 43 RunInternal(reinterpret_cast<uint8 *>(buffer.get()), data_size); | |
| 44 | |
| 45 std::wstring result(buffer.get()); | |
| 46 | |
| 47 // Clear the memory | |
| 48 memset(buffer.get(), 0, data_size); | |
| 49 return result; | |
| 50 } | |
| 51 | |
| 52 private: | |
| 53 static const int kKeyDataSize = 256; | |
| 54 struct Rc4Key { | |
| 55 uint8 state[kKeyDataSize]; | |
| 56 uint8 x; | |
| 57 uint8 y; | |
| 58 }; | |
| 59 | |
| 60 void SwapByte(uint8* byte1, uint8* byte2) { | |
| 61 uint8 temp = *byte1; | |
| 62 *byte1 = *byte2; | |
| 63 *byte2 = temp; | |
| 64 } | |
| 65 | |
| 66 void PrepareKey(const uint8 *key_data, int key_data_len) { | |
| 67 uint8 index1 = 0; | |
| 68 uint8 index2 = 0; | |
| 69 uint8* state; | |
| 70 short counter; | |
| 71 | |
| 72 state = &key_.state[0]; | |
| 73 for (counter = 0; counter < kKeyDataSize; ++counter) | |
| 74 state[counter] = static_cast<uint8>(counter); | |
| 75 | |
| 76 key_.x = key_.y = 0; | |
| 77 | |
| 78 for (counter = 0; counter < kKeyDataSize; counter++) { | |
| 79 index2 = (key_data[index1] + state[counter] + index2) % kKeyDataSize; | |
| 80 SwapByte(&state[counter], &state[index2]); | |
| 81 index1 = (index1 + 1) % key_data_len; | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 void RunInternal(uint8 *buffer, int buffer_len) { | |
| 86 uint8 x, y; | |
| 87 uint8 xor_index = 0; | |
| 88 uint8* state; | |
| 89 int counter; | |
| 90 | |
| 91 x = key_.x; | |
| 92 y = key_.y; | |
| 93 state = &key_.state[0]; | |
| 94 for (counter = 0; counter < buffer_len; ++counter) { | |
| 95 x = (x + 1) % kKeyDataSize; | |
| 96 y = (state[x] + y) % kKeyDataSize; | |
| 97 SwapByte(&state[x], &state[y]); | |
| 98 xor_index = (state[x] + state[y]) % kKeyDataSize; | |
| 99 buffer[counter] ^= state[xor_index]; | |
| 100 } | |
| 101 key_.x = x; | |
| 102 key_.y = y; | |
| 103 } | |
| 104 | |
| 105 Rc4Key key_; | |
| 106 }; | |
| 107 | |
| 108 } // namespace autofill | |
| 109 | |
| 110 #endif // COMPONENTS_AUTOFILL_BROWSER_CRYPTO_RC4_DECRYPTOR_H_ | |
| OLD | NEW |