Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sal / rtl / cipher.cxx
blob26d9cca29afcd89b52ed4c56ef7dd7b6ef1af09f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
22 #include <sal/types.h>
23 #include <rtl/alloc.h>
24 #include <rtl/cipher.h>
25 #include <algorithm>
26 #include <cassert>
27 #include <cstring>
28 #include <limits>
30 #if defined LIBO_CIPHER_OPENSSL_BACKEND
31 #include <openssl/evp.h>
32 #endif
34 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
35 #define RTL_CIPHER_NTOHL(c, l) \
36 ((l) = (static_cast<sal_uInt32>(*((c)++))) << 24, \
37 (l) |= (static_cast<sal_uInt32>(*((c)++))) << 16, \
38 (l) |= (static_cast<sal_uInt32>(*((c)++))) << 8, \
39 (l) |= (static_cast<sal_uInt32>(*((c)++))))
41 #define RTL_CIPHER_HTONL(l, c) \
42 (*((c)++) = static_cast<sal_uInt8>(((l) >> 24) & 0xff), \
43 *((c)++) = static_cast<sal_uInt8>(((l) >> 16) & 0xff), \
44 *((c)++) = static_cast<sal_uInt8>(((l) >> 8) & 0xff), \
45 *((c)++) = static_cast<sal_uInt8>(((l) ) & 0xff))
47 #define RTL_CIPHER_NTOHL64(c, xl, xr, n) \
48 { \
49 (xl) = (xr) = 0; \
50 (c) += (n); \
51 switch ((n)) \
52 { \
53 case 8: (xr) = (static_cast<sal_uInt32>(*(--(c)))); \
54 [[fallthrough]]; \
55 case 7: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 8; \
56 [[fallthrough]]; \
57 case 6: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 16; \
58 [[fallthrough]]; \
59 case 5: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 24; \
60 [[fallthrough]]; \
61 case 4: (xl) = (static_cast<sal_uInt32>(*(--(c)))); \
62 [[fallthrough]]; \
63 case 3: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 8; \
64 [[fallthrough]]; \
65 case 2: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 16; \
66 [[fallthrough]]; \
67 case 1: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 24; \
68 } \
71 #define RTL_CIPHER_HTONL64(xl, xr, c, n) \
72 { \
73 (c) += (n); \
74 switch ((n)) \
75 { \
76 case 8: *(--(c)) = static_cast<sal_uInt8>(((xr) ) & 0xff); \
77 [[fallthrough]]; \
78 case 7: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 8) & 0xff); \
79 [[fallthrough]]; \
80 case 6: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 16) & 0xff); \
81 [[fallthrough]]; \
82 case 5: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 24) & 0xff); \
83 [[fallthrough]]; \
84 case 4: *(--(c)) = static_cast<sal_uInt8>(((xl) ) & 0xff); \
85 [[fallthrough]]; \
86 case 3: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 8) & 0xff); \
87 [[fallthrough]]; \
88 case 2: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 16) & 0xff); \
89 [[fallthrough]]; \
90 case 1: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 24) & 0xff); \
91 } \
93 #endif
95 typedef rtlCipherError(cipher_init_t) (
96 rtlCipher Cipher,
97 rtlCipherDirection Direction,
98 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
99 const sal_uInt8 *pArgData, sal_Size nArgLen);
101 typedef rtlCipherError(cipher_update_t) (
102 rtlCipher Cipher,
103 const void *pData, sal_Size nDatLen,
104 sal_uInt8 *pBuffer, sal_Size nBufLen);
106 typedef void (cipher_delete_t) (rtlCipher Cipher);
108 struct Cipher_Impl
110 rtlCipherAlgorithm m_algorithm;
111 rtlCipherDirection m_direction;
112 rtlCipherMode m_mode;
114 cipher_init_t *m_init;
115 cipher_update_t *m_encode;
116 cipher_update_t *m_decode;
117 cipher_delete_t *m_delete;
120 rtlCipher SAL_CALL rtl_cipher_create(
121 rtlCipherAlgorithm Algorithm,
122 rtlCipherMode Mode) SAL_THROW_EXTERN_C()
124 rtlCipher Cipher = nullptr;
125 switch (Algorithm)
127 case rtl_Cipher_AlgorithmBF:
128 Cipher = rtl_cipher_createBF (Mode);
129 break;
131 case rtl_Cipher_AlgorithmARCFOUR:
132 Cipher = rtl_cipher_createARCFOUR (Mode);
133 break;
135 default: /* rtl_Cipher_AlgorithmInvalid */
136 break;
138 return Cipher;
141 rtlCipherError SAL_CALL rtl_cipher_init(
142 rtlCipher Cipher,
143 rtlCipherDirection Direction,
144 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
145 const sal_uInt8 *pArgData, sal_Size nArgLen) SAL_THROW_EXTERN_C()
147 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
148 if (!pImpl)
149 return rtl_Cipher_E_Argument;
151 if (!pImpl->m_init)
152 return rtl_Cipher_E_Unknown;
154 return (pImpl->m_init)(
155 Cipher, Direction, pKeyData, nKeyLen, pArgData, nArgLen);
158 rtlCipherError SAL_CALL rtl_cipher_encode(
159 rtlCipher Cipher,
160 const void *pData, sal_Size nDatLen,
161 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
163 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
164 if (!pImpl)
165 return rtl_Cipher_E_Argument;
167 if (!pImpl->m_encode)
168 return rtl_Cipher_E_Unknown;
170 return (pImpl->m_encode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
173 rtlCipherError SAL_CALL rtl_cipher_decode(
174 rtlCipher Cipher,
175 const void *pData, sal_Size nDatLen,
176 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
178 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
179 if (!pImpl)
180 return rtl_Cipher_E_Argument;
182 if (!pImpl->m_decode)
183 return rtl_Cipher_E_Unknown;
185 return (pImpl->m_decode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
188 void SAL_CALL rtl_cipher_destroy(rtlCipher Cipher) SAL_THROW_EXTERN_C()
190 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
191 if (pImpl && pImpl->m_delete)
192 pImpl->m_delete(Cipher);
195 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
196 #define CIPHER_ROUNDS_BF 16
198 struct CipherKeyBF
200 sal_uInt32 m_S[4][256];
201 sal_uInt32 m_P[CIPHER_ROUNDS_BF + 2];
203 #endif
205 struct CipherContextBF
207 #if defined LIBO_CIPHER_OPENSSL_BACKEND
208 EVP_CIPHER_CTX * m_context;
209 #else
210 CipherKeyBF m_key;
211 union
213 sal_uInt32 m_long[2];
214 sal_uInt8 m_byte[8];
215 } m_iv;
216 sal_uInt32 m_offset;
217 #endif
220 struct CipherBF_Impl
222 Cipher_Impl m_cipher;
223 CipherContextBF m_context;
226 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
227 static rtlCipherError BF_init(
228 CipherContextBF *ctx,
229 rtlCipherMode eMode,
230 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
231 const sal_uInt8 *pArgData, sal_Size nArgLen);
232 #endif
234 static rtlCipherError BF_update(
235 CipherContextBF *ctx,
236 rtlCipherMode eMode,
237 rtlCipherDirection eDirection,
238 const sal_uInt8 *pData, sal_Size nDatLen,
239 sal_uInt8 *pBuffer, sal_Size nBufLen);
241 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
242 static void BF_updateECB(
243 CipherContextBF *ctx,
244 rtlCipherDirection direction,
245 const sal_uInt8 *pData,
246 sal_uInt8 *pBuffer,
247 sal_Size nLength);
249 static void BF_updateCBC(
250 CipherContextBF *ctx,
251 rtlCipherDirection direction,
252 const sal_uInt8 *pData,
253 sal_uInt8 *pBuffer,
254 sal_Size nLength);
256 static void BF_updateCFB(
257 CipherContextBF *ctx,
258 rtlCipherDirection direction,
259 const sal_uInt8 *pData,
260 sal_uInt8 *pBuffer);
262 static void BF_encode(CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
264 static void BF_decode(CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
266 static sal_uInt32 BF(CipherKeyBF *key, sal_uInt32 x);
268 static const CipherKeyBF BF_key =
270 /* S */
272 /* S[0] */
274 /* 0 */
275 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
276 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
277 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
278 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
280 /* 1 */
281 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
282 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
283 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
284 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
286 /* 2 */
287 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
288 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
289 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
290 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
292 /* 3 */
293 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
294 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
295 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
296 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
298 /* 4 */
299 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
300 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
301 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
302 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
304 /* 5 */
305 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
306 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
307 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
308 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
310 /* 6 */
311 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
312 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
313 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
314 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
316 /* 7 */
317 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
318 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
319 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
320 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
322 /* 8 */
323 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
324 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
325 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
326 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
328 /* 9 */
329 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
330 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
331 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
332 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
334 /* A */
335 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
336 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
337 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
338 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
340 /* B */
341 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
342 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
343 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
344 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
346 /* C */
347 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
348 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
349 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
350 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
352 /* D */
353 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
354 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
355 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
356 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
358 /* E */
359 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
360 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
361 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
362 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
364 /* F */
365 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
366 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
367 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
368 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL
371 /* S[1] */
373 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
374 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
375 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
376 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
378 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
379 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
380 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
381 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
383 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
384 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
385 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
386 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
388 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
389 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
390 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
391 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
393 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
394 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
395 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
396 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
398 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
399 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
400 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
401 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
403 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
404 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
405 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
406 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
408 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
409 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
410 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
411 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
413 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
414 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
415 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
416 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
418 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
419 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
420 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
421 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
423 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
424 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
425 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
426 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
428 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
429 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
430 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
431 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
433 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
434 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
435 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
436 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
438 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
439 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
440 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
441 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
443 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
444 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
445 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
446 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
448 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
449 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
450 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
451 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L
454 /* S[2] */
456 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
457 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
458 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
459 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
461 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
462 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
463 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
464 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
466 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
467 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
468 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
469 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
471 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
472 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
473 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
474 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
476 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
477 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
478 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
479 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
481 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
482 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
483 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
484 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
486 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
487 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
488 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
489 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
491 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
492 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
493 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
494 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
496 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
497 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
498 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
499 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
501 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
502 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
503 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
504 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
506 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
507 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
508 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
509 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
511 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
512 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
513 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
514 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
516 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
517 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
518 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
519 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
521 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
522 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
523 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
524 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
526 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
527 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
528 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
529 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
531 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
532 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
533 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
534 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L
537 /* S[3] */
539 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
540 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
541 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
542 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
544 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
545 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
546 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
547 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
549 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
550 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
551 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
552 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
554 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
555 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
556 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
557 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
559 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
560 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
561 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
562 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
564 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
565 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
566 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
567 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
569 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
570 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
571 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
572 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
574 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
575 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
576 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
577 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
579 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
580 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
581 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
582 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
584 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
585 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
586 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
587 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
589 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
590 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
591 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
592 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
594 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
595 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
596 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
597 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
599 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
600 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
601 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
602 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
604 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
605 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
606 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
607 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
609 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
610 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
611 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
612 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
614 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
615 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
616 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
617 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L
621 /* P */
623 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
624 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
625 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
626 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
627 0x9216D5D9L, 0x8979FB1BL
630 #endif
632 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
633 static rtlCipherError BF_init(
634 CipherContextBF *ctx,
635 rtlCipherMode eMode,
636 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
637 const sal_uInt8 *pArgData, sal_Size nArgLen)
639 CipherKeyBF *key;
640 sal_uInt32 D, DL, DR;
641 sal_uInt16 i, j, k;
643 key = &(ctx->m_key);
645 memcpy(key, &BF_key, sizeof (CipherKeyBF));
646 memset(&(ctx->m_iv), 0, sizeof(ctx->m_iv));
647 ctx->m_offset = 0;
649 for (i = 0, k = 0; i < CIPHER_ROUNDS_BF + 2; ++i)
651 D = 0;
652 for (j = 0; j < 4; ++j)
654 D = ((D << 8) | pKeyData[k]);
655 k++;
656 if (k >= nKeyLen)
657 k = 0;
659 key->m_P[i] ^= D;
662 rtl_secureZeroMemory(&DL, sizeof(DL));
663 rtl_secureZeroMemory(&DR, sizeof(DR));
665 for (i = 0; i < CIPHER_ROUNDS_BF + 2; i += 2)
667 BF_encode(key, &DL, &DR);
668 key->m_P[i ] = DL;
669 key->m_P[i + 1] = DR;
672 for (i = 0; i < 4; ++i)
674 for (k = 0; k < 256; k += 2)
676 BF_encode(key, &DL, &DR);
677 key->m_S[i][k ] = DL;
678 key->m_S[i][k + 1] = DR;
682 if (pArgData && nArgLen)
684 nArgLen = std::min<sal_Size>(nArgLen, 8);
685 if (eMode == rtl_Cipher_ModeStream)
687 memcpy(ctx->m_iv.m_byte, pArgData, nArgLen);
689 else
691 RTL_CIPHER_NTOHL64 (pArgData, DL, DR, nArgLen);
692 ctx->m_iv.m_long[0] = DL;
693 ctx->m_iv.m_long[1] = DR;
697 return rtl_Cipher_E_None;
699 #endif
701 static rtlCipherError BF_update(
702 CipherContextBF *ctx,
703 rtlCipherMode eMode,
704 rtlCipherDirection eDirection,
705 const sal_uInt8 *pData, sal_Size nDatLen,
706 sal_uInt8 *pBuffer, sal_Size nBufLen)
708 /* Check arguments. */
709 if (!pData || !pBuffer)
710 return rtl_Cipher_E_Argument;
712 if (!((nDatLen > 0) && (nDatLen <= nBufLen)))
713 return rtl_Cipher_E_BufferSize;
715 /* Update. */
716 #if defined LIBO_CIPHER_OPENSSL_BACKEND
717 assert(eMode == rtl_Cipher_ModeStream);
718 (void) eMode;
719 (void) eDirection;
720 while (nDatLen > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
721 int outl;
722 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, std::numeric_limits<int>::max())
723 == 0)
725 return rtl_Cipher_E_Unknown;
727 assert(outl == std::numeric_limits<int>::max());
728 pData += std::numeric_limits<int>::max();
729 nDatLen -= std::numeric_limits<int>::max();
730 pBuffer += std::numeric_limits<int>::max();
732 int outl;
733 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, static_cast<int>(nDatLen)) == 0)
735 return rtl_Cipher_E_Unknown;
737 assert(outl == static_cast<int>(nDatLen));
738 // A final call to EVP_CipherFinal_ex is intentionally missing; it wouldn't fit the rtl/cipher.h
739 // interface, and is hopefully not needed, as each individual Blowfish CFB update step doesn't
740 // hold back any data that would need to be finally flushed.
741 #else
742 if (eMode == rtl_Cipher_ModeECB)
744 /* Block mode. */
745 while (nDatLen > 8)
747 BF_updateECB(ctx, eDirection, pData, pBuffer, 8);
748 nDatLen -= 8;
749 pData += 8;
750 pBuffer += 8;
752 BF_updateECB(ctx, eDirection, pData, pBuffer, nDatLen);
754 else if (eMode == rtl_Cipher_ModeCBC)
756 /* Block mode. */
757 while (nDatLen > 8)
759 BF_updateCBC (ctx, eDirection, pData, pBuffer, 8);
760 nDatLen -= 8;
761 pData += 8;
762 pBuffer += 8;
764 BF_updateCBC (ctx, eDirection, pData, pBuffer, nDatLen);
766 else
768 /* Stream mode. */
769 while (nDatLen > 0)
771 BF_updateCFB (ctx, eDirection, pData, pBuffer);
772 nDatLen -= 1;
773 pData += 1;
774 pBuffer += 1;
777 #endif
778 return rtl_Cipher_E_None;
781 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
782 static void BF_updateECB(
783 CipherContextBF *ctx,
784 rtlCipherDirection direction,
785 const sal_uInt8 *pData,
786 sal_uInt8 *pBuffer,
787 sal_Size nLength)
789 CipherKeyBF *key;
790 sal_uInt32 DL, DR;
792 key = &(ctx->m_key);
793 if (direction == rtl_Cipher_DirectionEncode)
795 RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
797 BF_encode(key, &DL, &DR);
799 RTL_CIPHER_HTONL(DL, pBuffer);
800 RTL_CIPHER_HTONL(DR, pBuffer);
802 else
804 RTL_CIPHER_NTOHL(pData, DL);
805 RTL_CIPHER_NTOHL(pData, DR);
807 BF_decode(key, &DL, &DR);
809 RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
811 rtl_secureZeroMemory(&DL, sizeof(DL));
812 rtl_secureZeroMemory(&DR, sizeof(DR));
815 static void BF_updateCBC(
816 CipherContextBF *ctx,
817 rtlCipherDirection direction,
818 const sal_uInt8 *pData,
819 sal_uInt8 *pBuffer,
820 sal_Size nLength)
822 CipherKeyBF *key;
823 sal_uInt32 DL, DR;
825 key = &(ctx->m_key);
826 if (direction == rtl_Cipher_DirectionEncode)
828 RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
830 DL ^= ctx->m_iv.m_long[0];
831 DR ^= ctx->m_iv.m_long[1];
833 BF_encode(key, &DL, &DR);
835 ctx->m_iv.m_long[0] = DL;
836 ctx->m_iv.m_long[1] = DR;
838 RTL_CIPHER_HTONL(DL, pBuffer);
839 RTL_CIPHER_HTONL(DR, pBuffer);
841 else
843 sal_uInt32 IVL, IVR;
845 RTL_CIPHER_NTOHL(pData, DL);
846 RTL_CIPHER_NTOHL(pData, DR);
848 IVL = DL;
849 IVR = DR;
851 BF_decode(key, &DL, &DR);
853 DL ^= ctx->m_iv.m_long[0];
854 DR ^= ctx->m_iv.m_long[1];
856 ctx->m_iv.m_long[0] = IVL;
857 ctx->m_iv.m_long[1] = IVR;
859 RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
861 rtl_secureZeroMemory(&DL, sizeof(DL));
862 rtl_secureZeroMemory(&DR, sizeof(DR));
865 static void BF_updateCFB(
866 CipherContextBF *ctx,
867 rtlCipherDirection direction,
868 const sal_uInt8 *pData,
869 sal_uInt8 *pBuffer)
871 sal_uInt8 *iv;
872 sal_uInt32 k;
874 iv = ctx->m_iv.m_byte;
875 k = ctx->m_offset;
877 if (k == 0)
879 sal_uInt32 IVL, IVR;
881 RTL_CIPHER_NTOHL64(iv, IVL, IVR, 8);
882 BF_encode(&(ctx->m_key), &IVL, &IVR);
883 RTL_CIPHER_HTONL64(IVL, IVR, iv, 8);
885 rtl_secureZeroMemory(&IVL, sizeof(IVL));
886 rtl_secureZeroMemory(&IVR, sizeof(IVR));
889 if (direction == rtl_Cipher_DirectionEncode)
891 iv[k] ^= *pData;
892 *pBuffer = iv[k];
894 else
896 sal_uInt8 c = iv[k];
897 iv[k] = *pData;
898 *pBuffer = *pData ^ c;
901 ctx->m_offset = ((k + 1) & 0x07);
902 iv = nullptr;
905 static void BF_encode(
906 CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
908 sal_uInt32 t, XL, XR;
909 sal_uInt16 i;
911 XL = *xl;
912 XR = *xr;
914 for (i = 0; i < CIPHER_ROUNDS_BF; ++i)
916 XL ^= key->m_P[i];
917 XR ^= BF (key, XL);
919 t = XL;
920 XL = XR;
921 XR = t;
924 t = XL;
925 XL = XR;
926 XR = t;
928 XR ^= key->m_P[CIPHER_ROUNDS_BF ];
929 XL ^= key->m_P[CIPHER_ROUNDS_BF + 1];
931 *xl = XL;
932 *xr = XR;
936 static void BF_decode(
937 CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
939 sal_uInt32 t, XL, XR;
940 sal_uInt16 i;
942 XL = *xl;
943 XR = *xr;
945 for (i = CIPHER_ROUNDS_BF + 1; i > 1; --i)
947 XL ^= key->m_P[i];
948 XR ^= BF (key, XL);
950 t = XL;
951 XL = XR;
952 XR = t;
955 t = XL;
956 XL = XR;
957 XR = t;
959 XR ^= key->m_P[1];
960 XL ^= key->m_P[0];
962 *xl = XL;
963 *xr = XR;
967 static sal_uInt32 BF(CipherKeyBF *key, sal_uInt32 x)
969 sal_uInt16 a, b, c, d;
970 sal_uInt32 y;
972 d = static_cast<sal_uInt16>(x & 0x00ff);
973 x >>= 8;
974 c = static_cast<sal_uInt16>(x & 0x00ff);
975 x >>= 8;
976 b = static_cast<sal_uInt16>(x & 0x00ff);
977 x >>= 8;
978 a = static_cast<sal_uInt16>(x & 0x00ff);
980 y = key->m_S[0][a];
981 y += key->m_S[1][b];
982 y ^= key->m_S[2][c];
983 y += key->m_S[3][d];
985 return y;
987 #endif
990 rtl_cipherBF (Blowfish) implementation.
992 Reference: Bruce Schneier: Applied Cryptography, 2nd edition, ch. 14.3
994 rtlCipher SAL_CALL rtl_cipher_createBF(rtlCipherMode Mode) SAL_THROW_EXTERN_C()
996 CipherBF_Impl *pImpl = nullptr;
998 if (Mode == rtl_Cipher_ModeInvalid)
999 return nullptr;
1000 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1001 if (Mode != rtl_Cipher_ModeStream) {
1002 // Cannot easily support ModeECB and ModeCBC, and they aren't used in the LO code at least:
1003 return nullptr;
1005 #endif
1007 pImpl = static_cast<CipherBF_Impl*>(rtl_allocateZeroMemory(sizeof (CipherBF_Impl)));
1008 if (pImpl)
1010 pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmBF;
1011 pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1012 pImpl->m_cipher.m_mode = Mode;
1014 pImpl->m_cipher.m_init = rtl_cipher_initBF;
1015 pImpl->m_cipher.m_encode = rtl_cipher_encodeBF;
1016 pImpl->m_cipher.m_decode = rtl_cipher_decodeBF;
1017 pImpl->m_cipher.m_delete = rtl_cipher_destroyBF;
1019 return static_cast<rtlCipher>(pImpl);
1022 rtlCipherError SAL_CALL rtl_cipher_initBF(
1023 rtlCipher Cipher,
1024 rtlCipherDirection Direction,
1025 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1026 const sal_uInt8 *pArgData, sal_Size nArgLen) SAL_THROW_EXTERN_C()
1028 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1030 if (!pImpl || !pKeyData)
1031 return rtl_Cipher_E_Argument;
1033 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1034 return rtl_Cipher_E_Algorithm;
1036 if (Direction != rtl_Cipher_DirectionInvalid)
1037 pImpl->m_cipher.m_direction = Direction;
1038 else
1039 return rtl_Cipher_E_Direction;
1041 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1042 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionBoth) {
1043 // Cannot easily support DirectionBoth, and it isn't used in the LO code at least:
1044 return rtl_Cipher_E_Direction;
1046 if (nKeyLen > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
1047 return rtl_Cipher_E_BufferSize;
1049 if (pImpl->m_context.m_context != nullptr) {
1050 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1052 pImpl->m_context.m_context = EVP_CIPHER_CTX_new();
1053 if (pImpl->m_context.m_context == nullptr) {
1054 return rtl_Cipher_E_Memory;
1056 unsigned char iv[8];
1057 auto const n = std::min(nArgLen, sal_Size(8));
1058 std::memcpy(iv, pArgData, n);
1059 std::memset(iv + n, 0, 8 - n);
1060 if (EVP_CipherInit_ex(
1061 pImpl->m_context.m_context, EVP_bf_cfb(), nullptr, nullptr, iv,
1062 pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode ? 0 : 1)
1063 == 0)
1065 return rtl_Cipher_E_Unknown;
1067 if (EVP_CIPHER_CTX_set_key_length(pImpl->m_context.m_context, static_cast<int>(nKeyLen)) == 0) {
1068 return rtl_Cipher_E_Unknown;
1070 if (EVP_CipherInit_ex(pImpl->m_context.m_context, nullptr, nullptr, pKeyData, nullptr, -1) == 0)
1072 return rtl_Cipher_E_Unknown;
1074 return rtl_Cipher_E_None;
1075 #else
1076 return BF_init(
1077 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1078 pKeyData, nKeyLen, pArgData, nArgLen);
1079 #endif
1082 rtlCipherError SAL_CALL rtl_cipher_encodeBF(
1083 rtlCipher Cipher,
1084 const void *pData, sal_Size nDatLen,
1085 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1087 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1088 if (!pImpl)
1089 return rtl_Cipher_E_Argument;
1091 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1092 return rtl_Cipher_E_Algorithm;
1094 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1095 return rtl_Cipher_E_Direction;
1097 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode)
1098 return rtl_Cipher_E_Direction;
1100 return BF_update(
1101 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1102 rtl_Cipher_DirectionEncode,
1103 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1106 rtlCipherError SAL_CALL rtl_cipher_decodeBF(
1107 rtlCipher Cipher,
1108 const void *pData, sal_Size nDatLen,
1109 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1111 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1112 if (!pImpl)
1113 return rtl_Cipher_E_Argument;
1115 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1116 return rtl_Cipher_E_Algorithm;
1118 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1119 return rtl_Cipher_E_Direction;
1121 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionEncode)
1122 return rtl_Cipher_E_Direction;
1124 return BF_update(
1125 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1126 rtl_Cipher_DirectionDecode,
1127 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1130 void SAL_CALL rtl_cipher_destroyBF(rtlCipher Cipher) SAL_THROW_EXTERN_C()
1132 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1133 if (pImpl)
1135 if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmBF)
1137 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1138 if (pImpl->m_context.m_context != nullptr) {
1139 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1141 #endif
1142 rtl_freeZeroMemory(pImpl, sizeof(CipherBF_Impl));
1144 else
1145 free(pImpl);
1149 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
1150 #define CIPHER_CBLOCK_ARCFOUR 256
1151 #endif
1153 struct ContextARCFOUR_Impl
1155 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1156 EVP_CIPHER_CTX * m_context;
1157 #else
1158 unsigned int m_S[CIPHER_CBLOCK_ARCFOUR];
1159 unsigned int m_X, m_Y;
1160 #endif
1163 struct CipherARCFOUR_Impl
1165 Cipher_Impl m_cipher;
1166 ContextARCFOUR_Impl m_context;
1169 static rtlCipherError rtl_cipherARCFOUR_update_Impl(
1170 ContextARCFOUR_Impl *ctx,
1171 const sal_uInt8 *pData, sal_Size nDatLen,
1172 sal_uInt8 *pBuffer, sal_Size nBufLen);
1174 static rtlCipherError rtl_cipherARCFOUR_init_Impl(
1175 ContextARCFOUR_Impl *ctx,
1176 const sal_uInt8 *pKeyData, sal_Size nKeyLen)
1178 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1179 if (nKeyLen > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
1180 return rtl_Cipher_E_BufferSize;
1182 if (ctx->m_context != nullptr) {
1183 EVP_CIPHER_CTX_free(ctx->m_context);
1185 ctx->m_context = EVP_CIPHER_CTX_new();
1186 if (ctx->m_context == nullptr) {
1187 return rtl_Cipher_E_Memory;
1189 if (EVP_CipherInit_ex(ctx->m_context, EVP_rc4(), nullptr, nullptr, nullptr, 0) == 0) {
1190 // RC4 en- and decryption is identical, so we can use 0=decrypt regardless of direction,
1191 // and thus also support rtl_Cipher_DirectionBoth
1192 return rtl_Cipher_E_Unknown;
1194 if (EVP_CIPHER_CTX_set_key_length(ctx->m_context, static_cast<int>(nKeyLen)) == 0) {
1195 return rtl_Cipher_E_Unknown;
1197 if (EVP_CipherInit_ex(ctx->m_context, nullptr, nullptr, pKeyData, nullptr, -1) == 0) {
1198 return rtl_Cipher_E_Unknown;
1200 #else
1201 unsigned int K[CIPHER_CBLOCK_ARCFOUR];
1202 unsigned int *L, *S;
1203 unsigned int x, y;
1204 sal_Size n, k;
1206 S = &(ctx->m_S[0]);
1208 /* Initialize S linearly. */
1209 for (x = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1210 S[x] = x;
1212 /* Initialize K with key, repeat key as necessary. */
1213 for (L = K, n = CIPHER_CBLOCK_ARCFOUR; n > nKeyLen; n -= nKeyLen)
1215 for (k = 0; k < nKeyLen; k++)
1217 L[k] = pKeyData[k];
1220 L += nKeyLen;
1223 for (k = 0; k < n; k++)
1225 L[k] = pKeyData[k];
1228 /* Initialize S with K. */
1229 for (x = 0, y = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1231 y = (y + S[x] + K[x]) % CIPHER_CBLOCK_ARCFOUR;
1232 /* swap S[x] and S[y] */
1233 unsigned int t = S[x];
1234 S[x] = S[y];
1235 S[y] = t;
1238 /* Initialize counters X and Y. */
1239 ctx->m_X = 0;
1240 ctx->m_Y = 0;
1241 #endif
1243 return rtl_Cipher_E_None;
1246 static rtlCipherError rtl_cipherARCFOUR_update_Impl(
1247 ContextARCFOUR_Impl *ctx,
1248 const sal_uInt8 *pData, sal_Size nDatLen,
1249 sal_uInt8 *pBuffer, sal_Size nBufLen)
1251 /* Check arguments. */
1252 if (!pData || !pBuffer)
1253 return rtl_Cipher_E_Argument;
1255 if (!((0 < nDatLen) && (nDatLen <= nBufLen)))
1256 return rtl_Cipher_E_BufferSize;
1258 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1259 while (nDatLen > static_cast<unsigned int>(std::numeric_limits<int>::max())) {
1260 int outl;
1261 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, std::numeric_limits<int>::max())
1262 == 0)
1264 return rtl_Cipher_E_Unknown;
1266 assert(outl == std::numeric_limits<int>::max());
1267 pData += std::numeric_limits<int>::max();
1268 nDatLen -= std::numeric_limits<int>::max();
1269 pBuffer += std::numeric_limits<int>::max();
1271 int outl;
1272 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, static_cast<int>(nDatLen)) == 0) {
1273 return rtl_Cipher_E_Unknown;
1275 assert(outl == static_cast<int>(nDatLen));
1276 // A final call to EVP_CipherFinal_ex is intentionally missing; it wouldn't fit the rtl/cipher.h
1277 // interface, and is hopefully not needed, as each individual RC4 update step doesn't hold back
1278 // any data that would need to be finally flushed.
1279 #else
1280 unsigned int *S;
1281 sal_Size k;
1283 /* Update. */
1284 S = &(ctx->m_S[0]);
1285 for (k = 0; k < nDatLen; k++)
1287 /* Update counters X and Y. */
1288 unsigned int x = ctx->m_X;
1289 unsigned int y = ctx->m_Y;
1290 x = (x + 1 ) % CIPHER_CBLOCK_ARCFOUR;
1291 y = (y + S[x]) % CIPHER_CBLOCK_ARCFOUR;
1292 ctx->m_X = x;
1293 ctx->m_Y = y;
1295 /* Swap S[x] and S[y]. */
1296 unsigned int t = S[x];
1297 S[x] = S[y];
1298 S[y] = t;
1300 /* Evaluate next key byte S[t]. */
1301 t = (S[x] + S[y]) % CIPHER_CBLOCK_ARCFOUR;
1302 pBuffer[k] = pData[k] ^ static_cast<sal_uInt8>(S[t] & 0xff);
1304 #endif
1306 return rtl_Cipher_E_None;
1310 rtl_cipher_ARCFOUR (RC4) implementation.
1312 Reference: Bruce Schneier: Applied Cryptography, 2nd edition, ch. 17.1
1314 rtlCipher SAL_CALL rtl_cipher_createARCFOUR(rtlCipherMode Mode)
1315 SAL_THROW_EXTERN_C()
1317 CipherARCFOUR_Impl *pImpl = nullptr;
1319 if (Mode != rtl_Cipher_ModeStream)
1320 return nullptr;
1322 pImpl = static_cast<CipherARCFOUR_Impl*>(rtl_allocateZeroMemory(sizeof(CipherARCFOUR_Impl)));
1323 if (pImpl)
1325 pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmARCFOUR;
1326 pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1327 pImpl->m_cipher.m_mode = rtl_Cipher_ModeStream;
1329 pImpl->m_cipher.m_init = rtl_cipher_initARCFOUR;
1330 pImpl->m_cipher.m_encode = rtl_cipher_encodeARCFOUR;
1331 pImpl->m_cipher.m_decode = rtl_cipher_decodeARCFOUR;
1332 pImpl->m_cipher.m_delete = rtl_cipher_destroyARCFOUR;
1335 return static_cast<rtlCipher>(pImpl);
1338 rtlCipherError SAL_CALL rtl_cipher_initARCFOUR(
1339 rtlCipher Cipher,
1340 rtlCipherDirection Direction,
1341 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1342 SAL_UNUSED_PARAMETER const sal_uInt8 *, SAL_UNUSED_PARAMETER sal_Size)
1343 SAL_THROW_EXTERN_C()
1345 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1347 if (!pImpl || !pKeyData)
1348 return rtl_Cipher_E_Argument;
1350 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1351 return rtl_Cipher_E_Algorithm;
1353 if (Direction != rtl_Cipher_DirectionInvalid)
1354 pImpl->m_cipher.m_direction = Direction;
1355 else
1356 return rtl_Cipher_E_Direction;
1358 return rtl_cipherARCFOUR_init_Impl(&(pImpl->m_context), pKeyData, nKeyLen);
1361 rtlCipherError SAL_CALL rtl_cipher_encodeARCFOUR(
1362 rtlCipher Cipher,
1363 const void *pData, sal_Size nDatLen,
1364 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1366 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1367 if (!pImpl)
1368 return rtl_Cipher_E_Argument;
1370 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1371 return rtl_Cipher_E_Algorithm;
1373 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1374 return rtl_Cipher_E_Direction;
1376 return rtl_cipherARCFOUR_update_Impl(
1377 &(pImpl->m_context),
1378 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1381 rtlCipherError SAL_CALL rtl_cipher_decodeARCFOUR(
1382 rtlCipher Cipher,
1383 const void *pData, sal_Size nDatLen,
1384 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1386 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1387 if (!pImpl)
1388 return rtl_Cipher_E_Argument;
1390 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1391 return rtl_Cipher_E_Algorithm;
1393 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1394 return rtl_Cipher_E_Direction;
1396 return rtl_cipherARCFOUR_update_Impl(
1397 &(pImpl->m_context),
1398 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1401 void SAL_CALL rtl_cipher_destroyARCFOUR(rtlCipher Cipher) SAL_THROW_EXTERN_C()
1403 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1404 if (pImpl)
1406 if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmARCFOUR)
1408 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1409 if (pImpl->m_context.m_context != nullptr) {
1410 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1412 #endif
1413 rtl_freeZeroMemory(pImpl, sizeof(CipherARCFOUR_Impl));
1415 else
1416 free(pImpl);
1420 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */