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