xref: /trunk/main/sal/rtl/source/cipher.c (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #define _RTL_CIPHER_C_ "$Revision: 1.5 $"
29 
30 #include <sal/types.h>
31 #include <rtl/alloc.h>
32 #include <rtl/memory.h>
33 #include <rtl/cipher.h>
34 
35 /*========================================================================
36  *
37  * rtlCipher internals.
38  *
39  *======================================================================*/
40 #define RTL_CIPHER_NTOHL(c, l) \
41 	((l)  = ((sal_uInt32)(*((c)++))) << 24L, \
42 	 (l) |= ((sal_uInt32)(*((c)++))) << 16L, \
43 	 (l) |= ((sal_uInt32)(*((c)++))) <<  8L, \
44 	 (l) |= ((sal_uInt32)(*((c)++))))
45 
46 #define RTL_CIPHER_HTONL(l, c) \
47 	(*((c)++) = (sal_uInt8)(((l) >> 24L) & 0xff), \
48 	 *((c)++) = (sal_uInt8)(((l) >> 16L) & 0xff), \
49 	 *((c)++) = (sal_uInt8)(((l) >>  8L) & 0xff), \
50 	 *((c)++) = (sal_uInt8)(((l)       ) & 0xff))
51 
52 #define RTL_CIPHER_NTOHL64(c, xl, xr, n) \
53 { \
54 	(xl) = (xr) = 0; \
55 	(c) += (n);  \
56 	switch ((n)) \
57 	{ \
58 		case 8: (xr)  = ((sal_uInt32)(*(--(c)))); \
59 		case 7: (xr) |= ((sal_uInt32)(*(--(c)))) <<  8L; \
60 		case 6: (xr) |= ((sal_uInt32)(*(--(c)))) << 16L; \
61 		case 5: (xr) |= ((sal_uInt32)(*(--(c)))) << 24L; \
62 		case 4: (xl)  = ((sal_uInt32)(*(--(c)))); \
63 		case 3: (xl) |= ((sal_uInt32)(*(--(c)))) <<  8L; \
64 		case 2: (xl) |= ((sal_uInt32)(*(--(c)))) << 16L; \
65 		case 1: (xl) |= ((sal_uInt32)(*(--(c)))) << 24L; \
66 	} \
67 }
68 
69 #define RTL_CIPHER_HTONL64(xl, xr, c, n) \
70 { \
71 	(c) += (n);  \
72 	switch ((n)) \
73 	{ \
74 		case 8: *(--(c)) = (sal_uInt8)(((xr)       ) & 0xff); \
75 		case 7: *(--(c)) = (sal_uInt8)(((xr) >>  8L) & 0xff); \
76 		case 6: *(--(c)) = (sal_uInt8)(((xr) >> 16L) & 0xff); \
77 		case 5: *(--(c)) = (sal_uInt8)(((xr) >> 24L) & 0xff); \
78 		case 4: *(--(c)) = (sal_uInt8)(((xl)       ) & 0xff); \
79 		case 3: *(--(c)) = (sal_uInt8)(((xl) >>  8L) & 0xff); \
80 		case 2: *(--(c)) = (sal_uInt8)(((xl) >> 16L) & 0xff); \
81 		case 1: *(--(c)) = (sal_uInt8)(((xl) >> 24L) & 0xff); \
82 	} \
83 }
84 
85 typedef rtlCipherError (SAL_CALL cipher_init_t) (
86 	rtlCipher          Cipher,
87 	rtlCipherDirection Direction,
88 	const sal_uInt8 *pKeyData, sal_Size nKeyLen,
89 	const sal_uInt8 *pArgData, sal_Size nArgLen);
90 
91 typedef rtlCipherError (SAL_CALL cipher_update_t) (
92 	rtlCipher   Cipher,
93 	const void *pData,   sal_Size nDatLen,
94 	sal_uInt8  *pBuffer, sal_Size nBufLen);
95 
96 typedef void (SAL_CALL cipher_delete_t) (rtlCipher Cipher);
97 
98 /** Cipher_Impl.
99  */
100 typedef struct cipher_impl_st
101 {
102 	rtlCipherAlgorithm  m_algorithm;
103 	rtlCipherDirection  m_direction;
104 	rtlCipherMode       m_mode;
105 
106 	cipher_init_t      *m_init;
107 	cipher_update_t    *m_encode;
108 	cipher_update_t    *m_decode;
109 	cipher_delete_t    *m_delete;
110 } Cipher_Impl;
111 
112 /*========================================================================
113  *
114  * rtlCipher implementation.
115  *
116  *======================================================================*/
117 /*
118  * rtl_cipher_create.
119  */
120 rtlCipher SAL_CALL rtl_cipher_create (
121 	rtlCipherAlgorithm Algorithm,
122 	rtlCipherMode      Mode)
123 {
124 	rtlCipher Cipher = (rtlCipher)NULL;
125 	switch (Algorithm)
126 	{
127 		case rtl_Cipher_AlgorithmBF:
128 			Cipher = rtl_cipher_createBF (Mode);
129 			break;
130 
131 		case rtl_Cipher_AlgorithmARCFOUR:
132 			Cipher = rtl_cipher_createARCFOUR (Mode);
133 			break;
134 
135 		default: /* rtl_Cipher_AlgorithmInvalid */
136 			break;
137 	}
138 	return Cipher;
139 }
140 
141 /*
142  * rtl_cipher_init.
143  */
144 rtlCipherError SAL_CALL rtl_cipher_init (
145 	rtlCipher          Cipher,
146 	rtlCipherDirection Direction,
147 	const sal_uInt8 *pKeyData, sal_Size nKeyLen,
148 	const sal_uInt8 *pArgData, sal_Size nArgLen)
149 {
150 	Cipher_Impl *pImpl = (Cipher_Impl*)Cipher;
151 	if (pImpl == NULL)
152 		return rtl_Cipher_E_Argument;
153 	if (pImpl->m_init == NULL)
154 		return rtl_Cipher_E_Unknown;
155 
156 	return (pImpl->m_init)(
157 		Cipher, Direction, pKeyData, nKeyLen, pArgData, nArgLen);
158 }
159 
160 /*
161  * rtl_cipher_encode.
162  */
163 rtlCipherError SAL_CALL rtl_cipher_encode (
164 	rtlCipher   Cipher,
165 	const void *pData,   sal_Size nDatLen,
166 	sal_uInt8  *pBuffer, sal_Size nBufLen)
167 {
168 	Cipher_Impl *pImpl = (Cipher_Impl*)Cipher;
169 	if (pImpl == NULL)
170 		return rtl_Cipher_E_Argument;
171 	if (pImpl->m_encode == NULL)
172 		return rtl_Cipher_E_Unknown;
173 
174 	return (pImpl->m_encode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
175 }
176 
177 /*
178  * rtl_cipher_decode.
179  */
180 rtlCipherError SAL_CALL rtl_cipher_decode (
181 	rtlCipher   Cipher,
182 	const void *pData,   sal_Size nDatLen,
183 	sal_uInt8  *pBuffer, sal_Size nBufLen)
184 {
185 	Cipher_Impl *pImpl = (Cipher_Impl*)Cipher;
186 	if (pImpl == NULL)
187 		return rtl_Cipher_E_Argument;
188 	if (pImpl->m_decode == NULL)
189 		return rtl_Cipher_E_Unknown;
190 
191 	return (pImpl->m_decode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
192 }
193 
194 /*
195  * rtl_cipher_destroy.
196  */
197 void SAL_CALL rtl_cipher_destroy (rtlCipher Cipher)
198 {
199 	Cipher_Impl *pImpl = (Cipher_Impl*)Cipher;
200 	if (pImpl && pImpl->m_delete)
201 		pImpl->m_delete (Cipher);
202 }
203 
204 /*========================================================================
205  *
206  * rtl_cipherBF (Blowfish) internals.
207  *
208  *======================================================================*/
209 #define CIPHER_ROUNDS_BF 16
210 
211 typedef struct cipherBF_key_st
212 {
213 	sal_uInt32 m_S[4][256];
214 	sal_uInt32 m_P[CIPHER_ROUNDS_BF + 2];
215 } CipherKeyBF;
216 
217 typedef struct cipherBF_context_st
218 {
219 	CipherKeyBF    m_key;
220 	union
221 	{
222 		sal_uInt32 m_long[2];
223 		sal_uInt8  m_byte[8];
224 	} m_iv;
225 	sal_uInt32     m_offset;
226 } CipherContextBF;
227 
228 typedef struct cipherBF_impl_st
229 {
230 	Cipher_Impl     m_cipher;
231 	CipherContextBF m_context;
232 } CipherBF_Impl;
233 
234 /** __rtl_cipherBF_init.
235  */
236 static rtlCipherError __rtl_cipherBF_init (
237 	CipherContextBF *ctx,
238 	rtlCipherMode    eMode,
239 	const sal_uInt8 *pKeyData, sal_Size nKeyLen,
240 	const sal_uInt8 *pArgData, sal_Size nArgLen);
241 
242 /** __rtl_cipherBF_update.
243  */
244 static rtlCipherError __rtl_cipherBF_update (
245 	CipherContextBF    *ctx,
246 	rtlCipherMode       eMode,
247 	rtlCipherDirection  eDirection,
248 	const sal_uInt8    *pData,   sal_Size nDatLen,
249 	sal_uInt8          *pBuffer, sal_Size nBufLen);
250 
251 /** __rtl_cipherBF_updateECB.
252  */
253 static void __rtl_cipherBF_updateECB (
254 	CipherContextBF    *ctx,
255 	rtlCipherDirection  direction,
256 	const sal_uInt8    *pData,
257 	sal_uInt8          *pBuffer,
258 	sal_Size            nLength);
259 
260 /** __rtl_cipherBF_updateCBC.
261  */
262 static void __rtl_cipherBF_updateCBC (
263 	CipherContextBF    *ctx,
264 	rtlCipherDirection  direction,
265 	const sal_uInt8    *pData,
266 	sal_uInt8          *pBuffer,
267 	sal_Size          nLength);
268 
269 /** __rtl_cipherBF_updateCFB.
270  */
271 static void __rtl_cipherBF_updateCFB (
272 	CipherContextBF    *ctx,
273 	rtlCipherDirection  direction,
274 	const sal_uInt8    *pData,
275 	sal_uInt8          *pBuffer);
276 
277 /** __rtl_cipher_encode.
278  */
279 static void __rtl_cipherBF_encode (
280 	CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
281 
282 /** __rtl_cipherBF_decode.
283  */
284 static void __rtl_cipherBF_decode (
285 	CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
286 
287 /** __rtl_cipherBF.
288  */
289 static sal_uInt32 __rtl_cipherBF (
290 	CipherKeyBF *key, sal_uInt32 x);
291 
292 /** __rtl_cipherBF_key.
293  */
294 static const CipherKeyBF __rtl_cipherBF_key =
295 {
296 	/* S */
297 	{
298 		/* S[0] */
299 		{
300 			/* 0 */
301 			0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
302 			0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
303 			0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
304 			0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
305 
306 			/* 1 */
307 			0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
308 			0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
309 			0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
310 			0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
311 
312 			/* 2 */
313 			0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
314 			0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
315 			0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
316 			0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
317 
318 			/* 3 */
319 			0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
320 			0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
321 			0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
322 			0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
323 
324 			/* 4 */
325 			0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
326 			0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
327 			0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
328 			0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
329 
330 			/* 5 */
331 			0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
332 			0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
333 			0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
334 			0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
335 
336 			/* 6 */
337 			0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
338 			0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
339 			0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
340 			0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
341 
342 			/* 7 */
343 			0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
344 			0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
345 			0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
346 			0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
347 
348 			/* 8 */
349 			0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
350 			0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
351 			0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
352 			0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
353 
354 			/* 9 */
355 			0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
356 			0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
357 			0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
358 			0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
359 
360 			/* A */
361 			0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
362 			0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
363 			0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
364 			0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
365 
366 			/* B */
367 			0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
368 			0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
369 			0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
370 			0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
371 
372 			/* C */
373 			0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
374 			0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
375 			0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
376 			0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
377 
378 			/* D */
379 			0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
380 			0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
381 			0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
382 			0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
383 
384 			/* E */
385 			0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
386 			0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
387 			0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
388 			0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
389 
390 			/* F */
391 			0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
392 			0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
393 			0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
394 			0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL
395 		},
396 
397 		/* S[1] */
398 		{
399 			0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
400 			0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
401 			0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
402 			0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
403 
404 			0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
405 			0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
406 			0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
407 			0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
408 
409 			0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
410 			0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
411 			0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
412 			0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
413 
414 			0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
415 			0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
416 			0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
417 			0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
418 
419 			0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
420 			0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
421 			0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
422 			0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
423 
424 			0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
425 			0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
426 			0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
427 			0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
428 
429 			0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
430 			0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
431 			0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
432 			0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
433 
434 			0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
435 			0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
436 			0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
437 			0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
438 
439 			0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
440 			0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
441 			0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
442 			0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
443 
444 			0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
445 			0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
446 			0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
447 			0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
448 
449 			0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
450 			0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
451 			0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
452 			0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
453 
454 			0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
455 			0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
456 			0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
457 			0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
458 
459 			0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
460 			0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
461 			0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
462 			0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
463 
464 			0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
465 			0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
466 			0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
467 			0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
468 
469 			0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
470 			0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
471 			0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
472 			0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
473 
474 			0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
475 			0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
476 			0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
477 			0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L
478 		},
479 
480 		/* S[2] */
481 		{
482 			0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
483 			0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
484 			0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
485 			0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
486 
487 			0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
488 			0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
489 			0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
490 			0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
491 
492 			0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
493 			0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
494 			0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
495 			0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
496 
497 			0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
498 			0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
499 			0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
500 			0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
501 
502 			0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
503 			0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
504 			0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
505 			0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
506 
507 			0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
508 			0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
509 			0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
510 			0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
511 
512 			0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
513 			0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
514 			0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
515 			0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
516 
517 			0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
518 			0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
519 			0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
520 			0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
521 
522 			0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
523 			0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
524 			0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
525 			0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
526 
527 			0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
528 			0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
529 			0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
530 			0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
531 
532 			0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
533 			0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
534 			0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
535 			0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
536 
537 			0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
538 			0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
539 			0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
540 			0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
541 
542 			0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
543 			0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
544 			0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
545 			0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
546 
547 			0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
548 			0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
549 			0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
550 			0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
551 
552 			0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
553 			0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
554 			0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
555 			0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
556 
557 			0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
558 			0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
559 			0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
560 			0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L
561 		},
562 
563 		/* S[3] */
564 		{
565 			0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
566 			0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
567 			0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
568 			0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
569 
570 			0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
571 			0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
572 			0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
573 			0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
574 
575 			0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
576 			0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
577 			0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
578 			0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
579 
580 			0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
581 			0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
582 			0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
583 			0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
584 
585 			0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
586 			0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
587 			0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
588 			0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
589 
590 			0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
591 			0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
592 			0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
593 			0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
594 
595 			0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
596 			0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
597 			0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
598 			0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
599 
600 			0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
601 			0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
602 			0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
603 			0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
604 
605 			0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
606 			0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
607 			0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
608 			0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
609 
610 			0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
611 			0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
612 			0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
613 			0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
614 
615 			0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
616 			0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
617 			0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
618 			0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
619 
620 			0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
621 			0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
622 			0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
623 			0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
624 
625 			0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
626 			0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
627 			0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
628 			0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
629 
630 			0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
631 			0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
632 			0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
633 			0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
634 
635 			0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
636 			0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
637 			0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
638 			0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
639 
640 			0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
641 			0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
642 			0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
643 			0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L
644 		}
645 	},
646 
647 	/* P */
648 	{
649 		0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
650 		0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
651 		0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
652 		0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
653 		0x9216D5D9L, 0x8979FB1BL
654 	}
655 };
656 
657 /*
658  * __rtl_cipherBF_init.
659  */
660 static rtlCipherError __rtl_cipherBF_init (
661 	CipherContextBF *ctx,
662 	rtlCipherMode    eMode,
663 	const sal_uInt8 *pKeyData, sal_Size nKeyLen,
664 	const sal_uInt8 *pArgData, sal_Size nArgLen)
665 {
666 	CipherKeyBF *key;
667 	sal_uInt32   D, DL, DR;
668 	sal_uInt16   i, j, k;
669 
670 	key = &(ctx->m_key);
671 
672 	rtl_copyMemory (key, &__rtl_cipherBF_key, sizeof (CipherKeyBF));
673 	rtl_zeroMemory (&(ctx->m_iv), sizeof(ctx->m_iv));
674 	ctx->m_offset = 0;
675 
676 	for (i = 0, k = 0; i < CIPHER_ROUNDS_BF + 2; ++i)
677 	{
678 		D = 0;
679 		for (j = 0; j < 4; ++j)
680 		{
681 			D = ((D << 8) | pKeyData[k]);
682 			k++;
683 			if (k >= nKeyLen)
684 				k = 0;
685 		}
686 		key->m_P[i] ^= D;
687 	}
688 
689 	DL = 0;
690 	DR = 0;
691 
692 	for (i = 0; i < CIPHER_ROUNDS_BF + 2; i += 2)
693 	{
694 		__rtl_cipherBF_encode (key, &DL, &DR);
695 		key->m_P[i    ] = DL;
696 		key->m_P[i + 1] = DR;
697 	}
698 
699 	for (i = 0; i < 4; ++i)
700 	{
701 		for (k = 0; k < 256; k += 2)
702 		{
703 			__rtl_cipherBF_encode (key, &DL, &DR);
704 			key->m_S[i][k    ] = DL;
705 			key->m_S[i][k + 1] = DR;
706 		}
707 	}
708 
709 	if (pArgData && nArgLen)
710 	{
711 		nArgLen = ((nArgLen < 8) ? nArgLen : 8);
712 		if (eMode == rtl_Cipher_ModeStream)
713 		{
714 			rtl_copyMemory (ctx->m_iv.m_byte, pArgData, nArgLen);
715 		}
716 		else
717 		{
718 			RTL_CIPHER_NTOHL64 (pArgData, DL, DR, nArgLen);
719 			ctx->m_iv.m_long[0] = DL;
720 			ctx->m_iv.m_long[1] = DR;
721 		}
722 	}
723 
724 	D = DL = DR = 0;
725 	return rtl_Cipher_E_None;
726 }
727 
728 /*
729  * __rtl_cipherBF_update.
730  */
731 static rtlCipherError __rtl_cipherBF_update (
732 	CipherContextBF    *ctx,
733 	rtlCipherMode       eMode,
734 	rtlCipherDirection  eDirection,
735 	const sal_uInt8    *pData,   sal_Size nDatLen,
736 	sal_uInt8          *pBuffer, sal_Size nBufLen)
737 {
738 	/* Check arguments. */
739 	if ((pData == NULL) || (pBuffer == NULL))
740 		return rtl_Cipher_E_Argument;
741 
742 	if (!((0 < nDatLen) && (nDatLen <= nBufLen)))
743 		return rtl_Cipher_E_BufferSize;
744 
745 	/* Update. */
746 	if (eMode == rtl_Cipher_ModeECB)
747 	{
748 		/* Block mode. */
749 		while (nDatLen > 8)
750 		{
751 			__rtl_cipherBF_updateECB (ctx, eDirection, pData, pBuffer, 8);
752 			nDatLen -= 8;
753 			pData   += 8;
754 			pBuffer += 8;
755 		}
756 		__rtl_cipherBF_updateECB (ctx, eDirection, pData, pBuffer, nDatLen);
757 	}
758 	else if (eMode == rtl_Cipher_ModeCBC)
759 	{
760 		/* Block mode. */
761 		while (nDatLen > 8)
762 		{
763 			__rtl_cipherBF_updateCBC (ctx, eDirection, pData, pBuffer, 8);
764 			nDatLen -= 8;
765 			pData   += 8;
766 			pBuffer += 8;
767 		}
768 		__rtl_cipherBF_updateCBC (ctx, eDirection, pData, pBuffer, nDatLen);
769 	}
770 	else
771 	{
772 		/* Stream mode. */
773 		while (nDatLen > 0)
774 		{
775 			__rtl_cipherBF_updateCFB (ctx, eDirection, pData, pBuffer);
776 			nDatLen -= 1;
777 			pData   += 1;
778 			pBuffer += 1;
779 		}
780 	}
781 	return rtl_Cipher_E_None;
782 }
783 
784 /*
785  * __rtl_cipherBF_updateECB.
786  */
787 static void __rtl_cipherBF_updateECB (
788 	CipherContextBF    *ctx,
789 	rtlCipherDirection  direction,
790 	const sal_uInt8    *pData,
791 	sal_uInt8          *pBuffer,
792 	sal_Size            nLength)
793 {
794 	CipherKeyBF *key;
795 	sal_uInt32   DL, DR;
796 
797 	key = &(ctx->m_key);
798 	if (direction == rtl_Cipher_DirectionEncode)
799 	{
800 		RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
801 
802 		__rtl_cipherBF_encode (key, &DL, &DR);
803 
804 		RTL_CIPHER_HTONL(DL, pBuffer);
805 		RTL_CIPHER_HTONL(DR, pBuffer);
806 	}
807 	else
808 	{
809 		RTL_CIPHER_NTOHL(pData, DL);
810 		RTL_CIPHER_NTOHL(pData, DR);
811 
812 		__rtl_cipherBF_decode (key, &DL, &DR);
813 
814 		RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
815 	}
816 	DL = DR = 0;
817 }
818 
819 /*
820  * __rtl_cipherBF_updateCBC.
821  */
822 static void __rtl_cipherBF_updateCBC (
823 	CipherContextBF    *ctx,
824 	rtlCipherDirection  direction,
825 	const sal_uInt8    *pData,
826 	sal_uInt8          *pBuffer,
827 	sal_Size            nLength)
828 {
829 	CipherKeyBF *key;
830 	sal_uInt32   DL, DR;
831 
832 	key = &(ctx->m_key);
833 	if (direction == rtl_Cipher_DirectionEncode)
834 	{
835 		RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
836 
837 		DL ^= ctx->m_iv.m_long[0];
838 		DR ^= ctx->m_iv.m_long[1];
839 
840 		__rtl_cipherBF_encode (key, &DL, &DR);
841 
842 		ctx->m_iv.m_long[0] = DL;
843 		ctx->m_iv.m_long[1] = DR;
844 
845 		RTL_CIPHER_HTONL(DL, pBuffer);
846 		RTL_CIPHER_HTONL(DR, pBuffer);
847 	}
848 	else
849 	{
850 		sal_uInt32 IVL, IVR;
851 
852 		RTL_CIPHER_NTOHL(pData, DL);
853 		RTL_CIPHER_NTOHL(pData, DR);
854 
855 		IVL = DL;
856 		IVR = DR;
857 
858 		__rtl_cipherBF_decode (key, &DL, &DR);
859 
860 		DL ^= ctx->m_iv.m_long[0];
861 		DR ^= ctx->m_iv.m_long[1];
862 
863 		ctx->m_iv.m_long[0] = IVL;
864 		ctx->m_iv.m_long[1] = IVR;
865 
866 		RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
867 		IVL = IVR = 0;
868 	}
869 	DL = DR = 0;
870 }
871 
872 /*
873  * __rtl_cipherBF_updateCFB.
874  */
875 static void __rtl_cipherBF_updateCFB (
876 	CipherContextBF    *ctx,
877 	rtlCipherDirection  direction,
878 	const sal_uInt8    *pData,
879 	sal_uInt8          *pBuffer)
880 {
881 	sal_uInt8  *iv;
882 	sal_uInt32  k;
883 
884 	iv = ctx->m_iv.m_byte;
885 	k  = ctx->m_offset;
886 
887 	if (k == 0)
888 	{
889 		sal_uInt32 IVL, IVR;
890 
891 		RTL_CIPHER_NTOHL64(iv, IVL, IVR, 8);
892 		__rtl_cipherBF_encode (&(ctx->m_key), &IVL, &IVR);
893 		RTL_CIPHER_HTONL64(IVL, IVR, iv, 8);
894 
895 		IVL = IVR = 0;
896 	}
897 
898 	if (direction == rtl_Cipher_DirectionEncode)
899 	{
900 		iv[k] ^= *pData;
901 		*pBuffer = iv[k];
902 	}
903 	else
904 	{
905 		sal_uInt8 c = iv[k];
906 		iv[k] = *pData;
907 		*pBuffer = *pData ^ c;
908 		c = 0;
909 	}
910 
911 	ctx->m_offset = ((k + 1) & 0x07);
912 	iv = NULL;
913 }
914 
915 /*
916  * __rtl_cipherBF_encode.
917  */
918 static void __rtl_cipherBF_encode (
919 	CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
920 {
921 	sal_uInt32  t, XL, XR;
922 	sal_uInt16  i;
923 
924 	XL = *xl;
925 	XR = *xr;
926 
927 	for (i = 0; i < CIPHER_ROUNDS_BF; ++i)
928 	{
929 		XL ^= key->m_P[i];
930 		XR ^= __rtl_cipherBF (key, XL);
931 
932 		t  = XL;
933 		XL = XR;
934 		XR = t;
935 	}
936 
937 	t  = XL;
938 	XL = XR;
939 	XR = t;
940 
941 	XR ^= key->m_P[CIPHER_ROUNDS_BF    ];
942 	XL ^= key->m_P[CIPHER_ROUNDS_BF + 1];
943 
944 	*xl = XL;
945 	*xr = XR;
946 
947 	t = XL = XR = 0;
948 }
949 
950 /*
951  * __rtl_cipherBF_decode.
952  */
953 static void __rtl_cipherBF_decode (
954 	CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
955 {
956 	sal_uInt32  t, XL, XR;
957 	sal_uInt16  i;
958 
959 	XL = *xl;
960 	XR = *xr;
961 
962 	for (i = CIPHER_ROUNDS_BF + 1; i > 1; --i)
963 	{
964 		XL ^= key->m_P[i];
965 		XR ^= __rtl_cipherBF (key, XL);
966 
967 		t  = XL;
968 		XL = XR;
969 		XR = t;
970 	}
971 
972 	t  = XL;
973 	XL = XR;
974 	XR = t;
975 
976 	XR ^= key->m_P[1];
977 	XL ^= key->m_P[0];
978 
979 	*xl = XL;
980 	*xr = XR;
981 
982 	t = XL = XR = 0;
983 }
984 
985 /*
986  * __rtl_cipherBF.
987  */
988 static sal_uInt32 __rtl_cipherBF (CipherKeyBF *key, sal_uInt32 x)
989 {
990 	sal_uInt16 a, b, c, d;
991 	sal_uInt32 y;
992 
993 	d = (sal_uInt16)(x & 0x00ff);
994 	x >>= 8;
995 	c = (sal_uInt16)(x & 0x00ff);
996 	x >>= 8;
997 	b = (sal_uInt16)(x & 0x00ff);
998 	x >>= 8;
999 	a = (sal_uInt16)(x & 0x00ff);
1000 
1001 	y  = key->m_S[0][a];
1002 	y += key->m_S[1][b];
1003 	y ^= key->m_S[2][c];
1004 	y += key->m_S[3][d];
1005 
1006 	return y;
1007 }
1008 
1009 /*========================================================================
1010  *
1011  * rtl_cipherBF (Blowfish) implementation.
1012  *
1013  * Reference:
1014  *   Bruce Schneier: Applied Cryptography, 2nd edition, ch. 14.3
1015  *
1016  *======================================================================*/
1017 /*
1018  * rtl_cipher_createBF.
1019  */
1020 rtlCipher SAL_CALL rtl_cipher_createBF (rtlCipherMode Mode)
1021 {
1022 	CipherBF_Impl *pImpl = (CipherBF_Impl*)NULL;
1023 
1024 	if (Mode == rtl_Cipher_ModeInvalid)
1025 		return ((rtlCipher)NULL);
1026 
1027 	pImpl = ((CipherBF_Impl*)rtl_allocateZeroMemory (sizeof (CipherBF_Impl)));
1028 	if (pImpl)
1029 	{
1030 		pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmBF;
1031 		pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1032 		pImpl->m_cipher.m_mode      = Mode;
1033 
1034 		pImpl->m_cipher.m_init      = rtl_cipher_initBF;
1035 		pImpl->m_cipher.m_encode    = rtl_cipher_encodeBF;
1036 		pImpl->m_cipher.m_decode    = rtl_cipher_decodeBF;
1037 		pImpl->m_cipher.m_delete    = rtl_cipher_destroyBF;
1038 	}
1039 	return ((rtlCipher)pImpl);
1040 }
1041 
1042 /*
1043  * rtl_cipher_initBF.
1044  */
1045 rtlCipherError SAL_CALL rtl_cipher_initBF (
1046 	rtlCipher          Cipher,
1047 	rtlCipherDirection Direction,
1048 	const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1049 	const sal_uInt8 *pArgData, sal_Size nArgLen)
1050 {
1051 	CipherBF_Impl *pImpl = (CipherBF_Impl*)Cipher;
1052 
1053 	if ((pImpl == NULL) || (pKeyData == NULL))
1054 		return rtl_Cipher_E_Argument;
1055 
1056 	if (!(pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmBF))
1057 		return rtl_Cipher_E_Algorithm;
1058 
1059 	if (!(Direction == rtl_Cipher_DirectionInvalid))
1060 		pImpl->m_cipher.m_direction = Direction;
1061 	else
1062 		return rtl_Cipher_E_Direction;
1063 
1064 	return __rtl_cipherBF_init (
1065 		&(pImpl->m_context), pImpl->m_cipher.m_mode,
1066 		pKeyData, nKeyLen, pArgData, nArgLen);
1067 }
1068 
1069 /*
1070  * rtl_cipher_encodeBF.
1071  */
1072 rtlCipherError SAL_CALL rtl_cipher_encodeBF (
1073 	rtlCipher   Cipher,
1074 	const void *pData,   sal_Size nDatLen,
1075 	sal_uInt8  *pBuffer, sal_Size nBufLen)
1076 {
1077 	CipherBF_Impl *pImpl = (CipherBF_Impl*)Cipher;
1078 	if (pImpl == NULL)
1079 		return rtl_Cipher_E_Argument;
1080 
1081 	if (!(pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmBF))
1082 		return rtl_Cipher_E_Algorithm;
1083 
1084 	if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1085 		return rtl_Cipher_E_Direction;
1086 	if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode)
1087 		return rtl_Cipher_E_Direction;
1088 
1089 	return __rtl_cipherBF_update (
1090 		&(pImpl->m_context), pImpl->m_cipher.m_mode,
1091 		rtl_Cipher_DirectionEncode,
1092 		(const sal_uInt8*)pData, nDatLen, pBuffer, nBufLen);
1093 }
1094 
1095 /*
1096  * rtl_cipher_decodeBF.
1097  */
1098 rtlCipherError SAL_CALL rtl_cipher_decodeBF (
1099 	rtlCipher   Cipher,
1100 	const void *pData,   sal_Size nDatLen,
1101 	sal_uInt8  *pBuffer, sal_Size nBufLen)
1102 {
1103 	CipherBF_Impl *pImpl = (CipherBF_Impl*)Cipher;
1104 	if (pImpl == NULL)
1105 		return rtl_Cipher_E_Argument;
1106 
1107 	if (!(pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmBF))
1108 		return rtl_Cipher_E_Algorithm;
1109 
1110 	if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1111 		return rtl_Cipher_E_Direction;
1112 	if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionEncode)
1113 		return rtl_Cipher_E_Direction;
1114 
1115 	return __rtl_cipherBF_update (
1116 		&(pImpl->m_context), pImpl->m_cipher.m_mode,
1117 		rtl_Cipher_DirectionDecode,
1118 		(const sal_uInt8*)pData, nDatLen, pBuffer, nBufLen);
1119 }
1120 
1121 /*
1122  * rtl_cipher_destroyBF.
1123  */
1124 void SAL_CALL rtl_cipher_destroyBF (rtlCipher Cipher)
1125 {
1126 	CipherBF_Impl *pImpl = (CipherBF_Impl*)Cipher;
1127 	if (pImpl)
1128 	{
1129 		if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmBF)
1130 			rtl_freeZeroMemory (pImpl, sizeof (CipherBF_Impl));
1131 		else
1132 			rtl_freeMemory (pImpl);
1133 	}
1134 }
1135 
1136 /*========================================================================
1137  *
1138  * rtl_cipher_ARCFOUR (RC4) internals.
1139  *
1140  *======================================================================*/
1141 #define CIPHER_CBLOCK_ARCFOUR 256
1142 
1143 typedef struct cipherARCFOUR_context_st
1144 {
1145 	unsigned int m_S[CIPHER_CBLOCK_ARCFOUR];
1146 	unsigned int m_X, m_Y;
1147 } ContextARCFOUR_Impl;
1148 
1149 typedef struct cipherARCFOUR_impl_st
1150 {
1151 	Cipher_Impl         m_cipher;
1152 	ContextARCFOUR_Impl m_context;
1153 } CipherARCFOUR_Impl;
1154 
1155 /** rtl_cipherARCFOUR_update_Impl.
1156  */
1157 static rtlCipherError rtl_cipherARCFOUR_update_Impl (
1158 	ContextARCFOUR_Impl *ctx,
1159 	const sal_uInt8     *pData,   sal_Size nDatLen,
1160 	sal_uInt8           *pBuffer, sal_Size nBufLen);
1161 
1162 /*
1163  * rtl_cipherARCFOUR_init_Impl.
1164  */
1165 static rtlCipherError rtl_cipherARCFOUR_init_Impl (
1166 	ContextARCFOUR_Impl *ctx,
1167 	const sal_uInt8     *pKeyData, sal_Size nKeyLen)
1168 {
1169 	unsigned int  K[CIPHER_CBLOCK_ARCFOUR];
1170 	unsigned int *L, *S;
1171 	unsigned int  x, y, t;
1172 	sal_Size      n, k;
1173 
1174 	S = &(ctx->m_S[0]);
1175 
1176 	/* Initialize S linearly. */
1177 	for (x = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1178 		S[x] = x;
1179 
1180 	/* Initialize K with key, repeat key as necessary. */
1181 	for (L = K, n = CIPHER_CBLOCK_ARCFOUR; n > nKeyLen; n -= nKeyLen)
1182 	{
1183 		for (k = 0; k < nKeyLen; k++) L[k] = pKeyData[k];
1184 		L += nKeyLen;
1185 	}
1186 	for (k = 0; k < n; k++) L[k] = pKeyData[k];
1187 
1188 	/* Initialize S with K. */
1189 	for (x = 0, y = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1190 	{
1191 		y = (y + S[x] + K[x]) % CIPHER_CBLOCK_ARCFOUR;
1192 		t = S[x], S[x] = S[y], S[y] = t; /* swap S[x] and S[y] */
1193 	}
1194 
1195 	/* Initialize counters X and Y. */
1196 	ctx->m_X = 0;
1197 	ctx->m_Y = 0;
1198 
1199 	return rtl_Cipher_E_None;
1200 }
1201 
1202 /*
1203  * rtl_cipherARCFOUR_update_Impl.
1204  */
1205 static rtlCipherError rtl_cipherARCFOUR_update_Impl (
1206 	ContextARCFOUR_Impl *ctx,
1207 	const sal_uInt8     *pData,   sal_Size nDatLen,
1208 	sal_uInt8           *pBuffer, sal_Size nBufLen)
1209 {
1210 	register unsigned int *S;
1211 	register unsigned int  x, y, t;
1212 	sal_Size               k;
1213 
1214 	/* Check arguments. */
1215 	if ((pData == NULL) || (pBuffer == NULL))
1216 		return rtl_Cipher_E_Argument;
1217 
1218 	if (!((0 < nDatLen) && (nDatLen <= nBufLen)))
1219 		return rtl_Cipher_E_BufferSize;
1220 
1221 	/* Update. */
1222 	S = &(ctx->m_S[0]);
1223 	for (k = 0; k < nDatLen; k++)
1224 	{
1225 		/* Update counters X and Y. */
1226 		x = ctx->m_X;
1227 		y = ctx->m_Y;
1228 		x = (x + 1   ) % CIPHER_CBLOCK_ARCFOUR;
1229 		y = (y + S[x]) % CIPHER_CBLOCK_ARCFOUR;
1230 		ctx->m_X = x;
1231 		ctx->m_Y = y;
1232 
1233 		/* Swap S[x] and S[y]. */
1234 		t = S[x], S[x] = S[y], S[y] = t;
1235 
1236 		/* Evaluate next key byte S[t]. */
1237 		t = (S[x] + S[y]) % CIPHER_CBLOCK_ARCFOUR;
1238 		pBuffer[k] = pData[k] ^ ((sal_uInt8)(S[t] & 0xff));
1239 	}
1240 
1241 	return rtl_Cipher_E_None;
1242 }
1243 
1244 /*========================================================================
1245  *
1246  * rtl_cipher_ARCFOUR (RC4) implementation.
1247  *
1248  * Reference:
1249  *   Bruce Schneier: Applied Cryptography, 2nd edition, ch. 17.1
1250  *
1251  *======================================================================*/
1252 /*
1253  * rtl_cipher_createARCFOUR.
1254  */
1255 rtlCipher SAL_CALL rtl_cipher_createARCFOUR (rtlCipherMode Mode)
1256 {
1257 	CipherARCFOUR_Impl *pImpl = (CipherARCFOUR_Impl*)NULL;
1258 
1259 	if (!(Mode == rtl_Cipher_ModeStream))
1260 		return ((rtlCipher)NULL);
1261 
1262 	pImpl = ((CipherARCFOUR_Impl*)rtl_allocateZeroMemory (sizeof (CipherARCFOUR_Impl)));
1263 	if (pImpl)
1264 	{
1265 		pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmARCFOUR;
1266 		pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1267 		pImpl->m_cipher.m_mode      = rtl_Cipher_ModeStream;
1268 
1269 		pImpl->m_cipher.m_init      = rtl_cipher_initARCFOUR;
1270 		pImpl->m_cipher.m_encode    = rtl_cipher_encodeARCFOUR;
1271 		pImpl->m_cipher.m_decode    = rtl_cipher_decodeARCFOUR;
1272 		pImpl->m_cipher.m_delete    = rtl_cipher_destroyARCFOUR;
1273 	}
1274 	return ((rtlCipher)pImpl);
1275 }
1276 
1277 /*
1278  * rtl_cipher_initARCFOUR.
1279  */
1280 rtlCipherError SAL_CALL rtl_cipher_initARCFOUR (
1281 	rtlCipher          Cipher,
1282 	rtlCipherDirection Direction,
1283 	const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1284 	const sal_uInt8 *pArgData, sal_Size nArgLen)
1285 {
1286 	CipherARCFOUR_Impl *pImpl = (CipherARCFOUR_Impl*)Cipher;
1287     (void) pArgData; // avoid warning
1288     (void) nArgLen; // avoid warning
1289 
1290 	if ((pImpl == NULL) || (pKeyData == NULL))
1291 		return rtl_Cipher_E_Argument;
1292 
1293 	if (!(pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmARCFOUR))
1294 		return rtl_Cipher_E_Algorithm;
1295 
1296 	if (!(Direction == rtl_Cipher_DirectionInvalid))
1297 		pImpl->m_cipher.m_direction = Direction;
1298 	else
1299 		return rtl_Cipher_E_Direction;
1300 
1301 	return rtl_cipherARCFOUR_init_Impl (&(pImpl->m_context), pKeyData, nKeyLen);
1302 }
1303 
1304 /*
1305  * rtl_cipher_encodeARCFOUR.
1306  */
1307 rtlCipherError SAL_CALL rtl_cipher_encodeARCFOUR (
1308 	rtlCipher   Cipher,
1309 	const void *pData,   sal_Size nDatLen,
1310 	sal_uInt8  *pBuffer, sal_Size nBufLen)
1311 {
1312 	CipherARCFOUR_Impl *pImpl = (CipherARCFOUR_Impl*)Cipher;
1313 	if (pImpl == NULL)
1314 		return rtl_Cipher_E_Argument;
1315 
1316 	if (!(pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmARCFOUR))
1317 		return rtl_Cipher_E_Algorithm;
1318 
1319 	if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1320 		return rtl_Cipher_E_Direction;
1321 
1322 	return rtl_cipherARCFOUR_update_Impl (
1323 		&(pImpl->m_context),
1324 		(const sal_uInt8*)pData, nDatLen, pBuffer, nBufLen);
1325 }
1326 
1327 /*
1328  * rtl_cipher_decodeARCFOUR.
1329  */
1330 rtlCipherError SAL_CALL rtl_cipher_decodeARCFOUR (
1331 	rtlCipher   Cipher,
1332 	const void *pData,   sal_Size nDatLen,
1333 	sal_uInt8  *pBuffer, sal_Size nBufLen)
1334 {
1335 	CipherARCFOUR_Impl *pImpl = (CipherARCFOUR_Impl*)Cipher;
1336 	if (pImpl == NULL)
1337 		return rtl_Cipher_E_Argument;
1338 
1339 	if (!(pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmARCFOUR))
1340 		return rtl_Cipher_E_Algorithm;
1341 
1342 	if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1343 		return rtl_Cipher_E_Direction;
1344 
1345 	return rtl_cipherARCFOUR_update_Impl (
1346 		&(pImpl->m_context),
1347 		(const sal_uInt8*)pData, nDatLen, pBuffer, nBufLen);
1348 }
1349 
1350 /*
1351  * rtl_cipher_destroyARCFOUR.
1352  */
1353 void SAL_CALL rtl_cipher_destroyARCFOUR (rtlCipher Cipher)
1354 {
1355 	CipherARCFOUR_Impl *pImpl = (CipherARCFOUR_Impl*)Cipher;
1356 	if (pImpl)
1357 	{
1358 		if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmARCFOUR)
1359 			rtl_freeZeroMemory (pImpl, sizeof (CipherARCFOUR_Impl));
1360 		else
1361 			rtl_freeMemory (pImpl);
1362 	}
1363 }
1364