1 // Copyright 2013 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.
5 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_CRYPTO_RC4_DECRYPTOR_H_
6 #define COMPONENTS_AUTOFILL_CORE_BROWSER_CRYPTO_RC4_DECRYPTOR_H_
9 #include "base/basictypes.h"
10 #include "base/memory/scoped_ptr.h"
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.
21 // components/autofill/core/browser/autofill_ie_toolbar_import_win.cc.
23 // This class should not be used anywhere else!!!
26 explicit RC4Decryptor(wchar_t const* password
) {
27 PrepareKey(reinterpret_cast<const uint8
*>(password
),
28 wcslen(password
) * sizeof(wchar_t));
30 // First 128 bytes should be spaces.
31 data
.resize(128, L
' ');
36 std::wstring
Run(const std::wstring
& data
) {
37 int data_size
= data
.length() * sizeof(wchar_t);
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
);
43 RunInternal(reinterpret_cast<uint8
*>(buffer
.get()), data_size
);
45 std::wstring
result(buffer
.get());
48 memset(buffer
.get(), 0, data_size
);
53 static const int kKeyDataSize
= 256;
55 uint8 state
[kKeyDataSize
];
60 void SwapByte(uint8
* byte1
, uint8
* byte2
) {
66 void PrepareKey(const uint8
*key_data
, int key_data_len
) {
72 state
= &key_
.state
[0];
73 for (counter
= 0; counter
< kKeyDataSize
; ++counter
)
74 state
[counter
] = static_cast<uint8
>(counter
);
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
;
85 void RunInternal(uint8
*buffer
, int buffer_len
) {
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
];
108 } // namespace autofill
110 #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CRYPTO_RC4_DECRYPTOR_H_