tdf#150621 Changed Korean word counting to use words
[LibreOffice.git] / sal / rtl / cipher.cxx
blob5d842c88f5f51cbc3bc649d8d5a053238e4d0ea2
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 <stdlib.h>
21 #include <string.h>
23 #include <sal/types.h>
24 #include <rtl/alloc.h>
25 #include <rtl/cipher.h>
26 #include <algorithm>
28 #if defined LIBO_CIPHER_OPENSSL_BACKEND
29 #include <o3tl/safeint.hxx>
30 #include <cassert>
31 #include <cstring>
32 #include <limits>
33 #include <openssl/evp.h>
34 #endif
36 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
37 #define RTL_CIPHER_NTOHL(c, l) \
38 ((l) = (static_cast<sal_uInt32>(*((c)++))) << 24, \
39 (l) |= (static_cast<sal_uInt32>(*((c)++))) << 16, \
40 (l) |= (static_cast<sal_uInt32>(*((c)++))) << 8, \
41 (l) |= (static_cast<sal_uInt32>(*((c)++))))
43 #define RTL_CIPHER_HTONL(l, c) \
44 (*((c)++) = static_cast<sal_uInt8>(((l) >> 24) & 0xff), \
45 *((c)++) = static_cast<sal_uInt8>(((l) >> 16) & 0xff), \
46 *((c)++) = static_cast<sal_uInt8>(((l) >> 8) & 0xff), \
47 *((c)++) = static_cast<sal_uInt8>(((l) ) & 0xff))
49 #define RTL_CIPHER_NTOHL64(c, xl, xr, n) \
50 { \
51 (xl) = (xr) = 0; \
52 (c) += (n); \
53 switch ((n)) \
54 { \
55 case 8: (xr) = (static_cast<sal_uInt32>(*(--(c)))); \
56 [[fallthrough]]; \
57 case 7: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 8; \
58 [[fallthrough]]; \
59 case 6: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 16; \
60 [[fallthrough]]; \
61 case 5: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 24; \
62 [[fallthrough]]; \
63 case 4: (xl) = (static_cast<sal_uInt32>(*(--(c)))); \
64 [[fallthrough]]; \
65 case 3: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 8; \
66 [[fallthrough]]; \
67 case 2: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 16; \
68 [[fallthrough]]; \
69 case 1: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 24; \
70 } \
73 #define RTL_CIPHER_HTONL64(xl, xr, c, n) \
74 { \
75 (c) += (n); \
76 switch ((n)) \
77 { \
78 case 8: *(--(c)) = static_cast<sal_uInt8>(((xr) ) & 0xff); \
79 [[fallthrough]]; \
80 case 7: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 8) & 0xff); \
81 [[fallthrough]]; \
82 case 6: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 16) & 0xff); \
83 [[fallthrough]]; \
84 case 5: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 24) & 0xff); \
85 [[fallthrough]]; \
86 case 4: *(--(c)) = static_cast<sal_uInt8>(((xl) ) & 0xff); \
87 [[fallthrough]]; \
88 case 3: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 8) & 0xff); \
89 [[fallthrough]]; \
90 case 2: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 16) & 0xff); \
91 [[fallthrough]]; \
92 case 1: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 24) & 0xff); \
93 } \
95 #endif
97 typedef rtlCipherError(cipher_init_t) (
98 rtlCipher Cipher,
99 rtlCipherDirection Direction,
100 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
101 const sal_uInt8 *pArgData, sal_Size nArgLen);
103 typedef rtlCipherError(cipher_update_t) (
104 rtlCipher Cipher,
105 const void *pData, sal_Size nDatLen,
106 sal_uInt8 *pBuffer, sal_Size nBufLen);
108 typedef void (cipher_delete_t) (rtlCipher Cipher);
110 namespace {
112 struct Cipher_Impl
114 rtlCipherAlgorithm m_algorithm;
115 rtlCipherDirection m_direction;
116 rtlCipherMode m_mode;
118 cipher_init_t *m_init;
119 cipher_update_t *m_encode;
120 cipher_update_t *m_decode;
121 cipher_delete_t *m_delete;
126 rtlCipher SAL_CALL rtl_cipher_create(
127 rtlCipherAlgorithm Algorithm,
128 rtlCipherMode Mode) SAL_THROW_EXTERN_C()
130 rtlCipher Cipher = nullptr;
131 switch (Algorithm)
133 case rtl_Cipher_AlgorithmBF:
134 Cipher = rtl_cipher_createBF (Mode);
135 break;
137 case rtl_Cipher_AlgorithmARCFOUR:
138 Cipher = rtl_cipher_createARCFOUR (Mode);
139 break;
141 default: /* rtl_Cipher_AlgorithmInvalid */
142 break;
144 return Cipher;
147 rtlCipherError SAL_CALL rtl_cipher_init(
148 rtlCipher Cipher,
149 rtlCipherDirection Direction,
150 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
151 const sal_uInt8 *pArgData, sal_Size nArgLen) SAL_THROW_EXTERN_C()
153 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
154 if (!pImpl)
155 return rtl_Cipher_E_Argument;
157 if (!pImpl->m_init)
158 return rtl_Cipher_E_Unknown;
160 return (pImpl->m_init)(
161 Cipher, Direction, pKeyData, nKeyLen, pArgData, nArgLen);
164 rtlCipherError SAL_CALL rtl_cipher_encode(
165 rtlCipher Cipher,
166 const void *pData, sal_Size nDatLen,
167 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
169 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
170 if (!pImpl)
171 return rtl_Cipher_E_Argument;
173 if (!pImpl->m_encode)
174 return rtl_Cipher_E_Unknown;
176 return (pImpl->m_encode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
179 rtlCipherError SAL_CALL rtl_cipher_decode(
180 rtlCipher Cipher,
181 const void *pData, sal_Size nDatLen,
182 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
184 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
185 if (!pImpl)
186 return rtl_Cipher_E_Argument;
188 if (!pImpl->m_decode)
189 return rtl_Cipher_E_Unknown;
191 return (pImpl->m_decode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
194 void SAL_CALL rtl_cipher_destroy(rtlCipher Cipher) SAL_THROW_EXTERN_C()
196 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
197 if (pImpl && pImpl->m_delete)
198 pImpl->m_delete(Cipher);
201 namespace {
203 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
204 #define CIPHER_ROUNDS_BF 16
206 struct CipherKeyBF
208 sal_uInt32 m_S[4][256];
209 sal_uInt32 m_P[CIPHER_ROUNDS_BF + 2];
211 #endif
213 struct CipherContextBF
215 #if defined LIBO_CIPHER_OPENSSL_BACKEND
216 EVP_CIPHER_CTX * m_context;
217 #else
218 CipherKeyBF m_key;
219 union
221 sal_uInt32 m_long[2];
222 sal_uInt8 m_byte[8];
223 } m_iv;
224 sal_uInt32 m_offset;
225 #endif
228 struct CipherBF_Impl
230 Cipher_Impl m_cipher;
231 CipherContextBF m_context;
236 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
237 static rtlCipherError BF_init(
238 CipherContextBF *ctx,
239 rtlCipherMode eMode,
240 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
241 const sal_uInt8 *pArgData, sal_Size nArgLen);
242 #endif
244 static rtlCipherError BF_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);
251 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
252 static void BF_updateECB(
253 CipherContextBF *ctx,
254 rtlCipherDirection direction,
255 const sal_uInt8 *pData,
256 sal_uInt8 *pBuffer,
257 sal_Size nLength);
259 static void BF_updateCBC(
260 CipherContextBF *ctx,
261 rtlCipherDirection direction,
262 const sal_uInt8 *pData,
263 sal_uInt8 *pBuffer,
264 sal_Size nLength);
266 static void BF_updateCFB(
267 CipherContextBF *ctx,
268 rtlCipherDirection direction,
269 const sal_uInt8 *pData,
270 sal_uInt8 *pBuffer);
272 static void BF_encode(CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
274 static void BF_decode(CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
276 static sal_uInt32 BF(CipherKeyBF *key, sal_uInt32 x);
278 const CipherKeyBF BF_key =
280 /* S */
282 /* S[0] */
284 /* 0 */
285 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
286 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
287 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
288 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
290 /* 1 */
291 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
292 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
293 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
294 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
296 /* 2 */
297 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
298 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
299 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
300 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
302 /* 3 */
303 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
304 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
305 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
306 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
308 /* 4 */
309 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
310 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
311 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
312 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
314 /* 5 */
315 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
316 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
317 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
318 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
320 /* 6 */
321 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
322 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
323 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
324 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
326 /* 7 */
327 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
328 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
329 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
330 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
332 /* 8 */
333 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
334 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
335 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
336 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
338 /* 9 */
339 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
340 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
341 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
342 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
344 /* A */
345 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
346 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
347 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
348 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
350 /* B */
351 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
352 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
353 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
354 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
356 /* C */
357 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
358 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
359 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
360 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
362 /* D */
363 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
364 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
365 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
366 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
368 /* E */
369 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
370 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
371 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
372 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
374 /* F */
375 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
376 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
377 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
378 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL
381 /* S[1] */
383 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
384 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
385 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
386 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
388 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
389 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
390 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
391 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
393 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
394 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
395 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
396 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
398 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
399 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
400 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
401 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
403 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
404 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
405 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
406 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
408 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
409 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
410 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
411 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
413 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
414 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
415 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
416 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
418 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
419 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
420 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
421 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
423 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
424 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
425 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
426 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
428 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
429 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
430 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
431 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
433 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
434 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
435 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
436 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
438 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
439 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
440 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
441 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
443 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
444 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
445 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
446 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
448 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
449 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
450 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
451 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
453 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
454 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
455 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
456 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
458 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
459 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
460 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
461 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L
464 /* S[2] */
466 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
467 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
468 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
469 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
471 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
472 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
473 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
474 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
476 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
477 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
478 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
479 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
481 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
482 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
483 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
484 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
486 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
487 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
488 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
489 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
491 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
492 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
493 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
494 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
496 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
497 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
498 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
499 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
501 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
502 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
503 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
504 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
506 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
507 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
508 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
509 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
511 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
512 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
513 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
514 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
516 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
517 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
518 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
519 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
521 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
522 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
523 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
524 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
526 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
527 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
528 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
529 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
531 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
532 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
533 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
534 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
536 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
537 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
538 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
539 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
541 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
542 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
543 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
544 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L
547 /* S[3] */
549 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
550 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
551 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
552 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
554 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
555 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
556 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
557 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
559 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
560 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
561 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
562 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
564 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
565 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
566 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
567 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
569 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
570 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
571 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
572 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
574 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
575 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
576 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
577 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
579 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
580 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
581 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
582 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
584 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
585 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
586 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
587 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
589 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
590 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
591 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
592 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
594 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
595 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
596 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
597 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
599 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
600 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
601 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
602 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
604 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
605 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
606 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
607 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
609 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
610 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
611 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
612 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
614 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
615 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
616 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
617 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
619 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
620 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
621 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
622 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
624 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
625 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
626 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
627 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L
631 /* P */
633 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
634 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
635 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
636 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
637 0x9216D5D9L, 0x8979FB1BL
640 #endif
642 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
643 static rtlCipherError BF_init(
644 CipherContextBF *ctx,
645 rtlCipherMode eMode,
646 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
647 const sal_uInt8 *pArgData, sal_Size nArgLen)
649 CipherKeyBF *key;
650 sal_uInt32 D, DL, DR;
651 sal_uInt16 i, j, k;
653 key = &(ctx->m_key);
655 memcpy(key, &BF_key, sizeof (CipherKeyBF));
656 memset(&(ctx->m_iv), 0, sizeof(ctx->m_iv));
657 ctx->m_offset = 0;
659 for (i = 0, k = 0; i < CIPHER_ROUNDS_BF + 2; ++i)
661 D = 0;
662 for (j = 0; j < 4; ++j)
664 D = ((D << 8) | pKeyData[k]);
665 k++;
666 if (k >= nKeyLen)
667 k = 0;
669 key->m_P[i] ^= D;
672 rtl_secureZeroMemory(&DL, sizeof(DL));
673 rtl_secureZeroMemory(&DR, sizeof(DR));
675 for (i = 0; i < CIPHER_ROUNDS_BF + 2; i += 2)
677 BF_encode(key, &DL, &DR);
678 key->m_P[i ] = DL;
679 key->m_P[i + 1] = DR;
682 for (i = 0; i < 4; ++i)
684 for (k = 0; k < 256; k += 2)
686 BF_encode(key, &DL, &DR);
687 key->m_S[i][k ] = DL;
688 key->m_S[i][k + 1] = DR;
692 if (pArgData && nArgLen)
694 nArgLen = std::min<sal_Size>(nArgLen, 8);
695 if (eMode == rtl_Cipher_ModeStream)
697 memcpy(ctx->m_iv.m_byte, pArgData, nArgLen);
699 else
701 RTL_CIPHER_NTOHL64 (pArgData, DL, DR, nArgLen);
702 ctx->m_iv.m_long[0] = DL;
703 ctx->m_iv.m_long[1] = DR;
707 return rtl_Cipher_E_None;
709 #endif
711 static rtlCipherError BF_update(
712 CipherContextBF *ctx,
713 rtlCipherMode eMode,
714 rtlCipherDirection eDirection,
715 const sal_uInt8 *pData, sal_Size nDatLen,
716 sal_uInt8 *pBuffer, sal_Size nBufLen)
718 /* Check arguments. */
719 if (!pData || !pBuffer)
720 return rtl_Cipher_E_Argument;
722 if ((nDatLen <= 0) || (nDatLen > nBufLen))
723 return rtl_Cipher_E_BufferSize;
725 /* Update. */
726 #if defined LIBO_CIPHER_OPENSSL_BACKEND
727 assert(eMode == rtl_Cipher_ModeStream);
728 (void) eMode;
729 (void) eDirection;
730 while (nDatLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
731 int outl;
732 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, std::numeric_limits<int>::max())
733 == 0)
735 return rtl_Cipher_E_Unknown;
737 assert(outl == std::numeric_limits<int>::max());
738 pData += std::numeric_limits<int>::max();
739 nDatLen -= std::numeric_limits<int>::max();
740 pBuffer += std::numeric_limits<int>::max();
742 int outl;
743 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, static_cast<int>(nDatLen)) == 0)
745 return rtl_Cipher_E_Unknown;
747 assert(outl == static_cast<int>(nDatLen));
748 // A final call to EVP_CipherFinal_ex is intentionally missing; it wouldn't fit the rtl/cipher.h
749 // interface, and is hopefully not needed, as each individual Blowfish CFB update step doesn't
750 // hold back any data that would need to be finally flushed.
751 #else
752 if (eMode == rtl_Cipher_ModeECB)
754 /* Block mode. */
755 while (nDatLen > 8)
757 BF_updateECB(ctx, eDirection, pData, pBuffer, 8);
758 nDatLen -= 8;
759 pData += 8;
760 pBuffer += 8;
762 BF_updateECB(ctx, eDirection, pData, pBuffer, nDatLen);
764 else if (eMode == rtl_Cipher_ModeCBC)
766 /* Block mode. */
767 while (nDatLen > 8)
769 BF_updateCBC (ctx, eDirection, pData, pBuffer, 8);
770 nDatLen -= 8;
771 pData += 8;
772 pBuffer += 8;
774 BF_updateCBC (ctx, eDirection, pData, pBuffer, nDatLen);
776 else
778 /* Stream mode. */
779 while (nDatLen > 0)
781 BF_updateCFB (ctx, eDirection, pData, pBuffer);
782 nDatLen -= 1;
783 pData += 1;
784 pBuffer += 1;
787 #endif
788 return rtl_Cipher_E_None;
791 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
792 static void BF_updateECB(
793 CipherContextBF *ctx,
794 rtlCipherDirection direction,
795 const sal_uInt8 *pData,
796 sal_uInt8 *pBuffer,
797 sal_Size nLength)
799 CipherKeyBF *key;
800 sal_uInt32 DL, DR;
802 key = &(ctx->m_key);
803 if (direction == rtl_Cipher_DirectionEncode)
805 RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
807 BF_encode(key, &DL, &DR);
809 RTL_CIPHER_HTONL(DL, pBuffer);
810 RTL_CIPHER_HTONL(DR, pBuffer);
812 else
814 RTL_CIPHER_NTOHL(pData, DL);
815 RTL_CIPHER_NTOHL(pData, DR);
817 BF_decode(key, &DL, &DR);
819 RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
821 rtl_secureZeroMemory(&DL, sizeof(DL));
822 rtl_secureZeroMemory(&DR, sizeof(DR));
825 static void BF_updateCBC(
826 CipherContextBF *ctx,
827 rtlCipherDirection direction,
828 const sal_uInt8 *pData,
829 sal_uInt8 *pBuffer,
830 sal_Size nLength)
832 CipherKeyBF *key;
833 sal_uInt32 DL, DR;
835 key = &(ctx->m_key);
836 if (direction == rtl_Cipher_DirectionEncode)
838 RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
840 DL ^= ctx->m_iv.m_long[0];
841 DR ^= ctx->m_iv.m_long[1];
843 BF_encode(key, &DL, &DR);
845 ctx->m_iv.m_long[0] = DL;
846 ctx->m_iv.m_long[1] = DR;
848 RTL_CIPHER_HTONL(DL, pBuffer);
849 RTL_CIPHER_HTONL(DR, pBuffer);
851 else
853 sal_uInt32 IVL, IVR;
855 RTL_CIPHER_NTOHL(pData, DL);
856 RTL_CIPHER_NTOHL(pData, DR);
858 IVL = DL;
859 IVR = DR;
861 BF_decode(key, &DL, &DR);
863 DL ^= ctx->m_iv.m_long[0];
864 DR ^= ctx->m_iv.m_long[1];
866 ctx->m_iv.m_long[0] = IVL;
867 ctx->m_iv.m_long[1] = IVR;
869 RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
871 rtl_secureZeroMemory(&DL, sizeof(DL));
872 rtl_secureZeroMemory(&DR, sizeof(DR));
875 static void BF_updateCFB(
876 CipherContextBF *ctx,
877 rtlCipherDirection direction,
878 const sal_uInt8 *pData,
879 sal_uInt8 *pBuffer)
881 sal_uInt8 *iv;
882 sal_uInt32 k;
884 iv = ctx->m_iv.m_byte;
885 k = ctx->m_offset;
887 if (k == 0)
889 sal_uInt32 IVL, IVR;
891 RTL_CIPHER_NTOHL64(iv, IVL, IVR, 8);
892 BF_encode(&(ctx->m_key), &IVL, &IVR);
893 RTL_CIPHER_HTONL64(IVL, IVR, iv, 8);
895 rtl_secureZeroMemory(&IVL, sizeof(IVL));
896 rtl_secureZeroMemory(&IVR, sizeof(IVR));
899 if (direction == rtl_Cipher_DirectionEncode)
901 iv[k] ^= *pData;
902 *pBuffer = iv[k];
904 else
906 sal_uInt8 c = iv[k];
907 iv[k] = *pData;
908 *pBuffer = *pData ^ c;
911 ctx->m_offset = ((k + 1) & 0x07);
912 iv = nullptr;
915 static void BF_encode(
916 CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
918 sal_uInt32 t, XL, XR;
919 sal_uInt16 i;
921 XL = *xl;
922 XR = *xr;
924 for (i = 0; i < CIPHER_ROUNDS_BF; ++i)
926 XL ^= key->m_P[i];
927 XR ^= BF (key, XL);
929 t = XL;
930 XL = XR;
931 XR = t;
934 t = XL;
935 XL = XR;
936 XR = t;
938 XR ^= key->m_P[CIPHER_ROUNDS_BF ];
939 XL ^= key->m_P[CIPHER_ROUNDS_BF + 1];
941 *xl = XL;
942 *xr = XR;
946 static void BF_decode(
947 CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
949 sal_uInt32 t, XL, XR;
950 sal_uInt16 i;
952 XL = *xl;
953 XR = *xr;
955 for (i = CIPHER_ROUNDS_BF + 1; i > 1; --i)
957 XL ^= key->m_P[i];
958 XR ^= BF (key, XL);
960 t = XL;
961 XL = XR;
962 XR = t;
965 t = XL;
966 XL = XR;
967 XR = t;
969 XR ^= key->m_P[1];
970 XL ^= key->m_P[0];
972 *xl = XL;
973 *xr = XR;
977 static sal_uInt32 BF(CipherKeyBF *key, sal_uInt32 x)
979 sal_uInt16 a, b, c, d;
980 sal_uInt32 y;
982 d = static_cast<sal_uInt16>(x & 0x00ff);
983 x >>= 8;
984 c = static_cast<sal_uInt16>(x & 0x00ff);
985 x >>= 8;
986 b = static_cast<sal_uInt16>(x & 0x00ff);
987 x >>= 8;
988 a = static_cast<sal_uInt16>(x & 0x00ff);
990 y = key->m_S[0][a];
991 y += key->m_S[1][b];
992 y ^= key->m_S[2][c];
993 y += key->m_S[3][d];
995 return y;
997 #endif
1000 rtl_cipherBF (Blowfish) implementation.
1002 Reference: Bruce Schneier: Applied Cryptography, 2nd edition, ch. 14.3
1004 rtlCipher SAL_CALL rtl_cipher_createBF(rtlCipherMode Mode) SAL_THROW_EXTERN_C()
1006 CipherBF_Impl *pImpl = nullptr;
1008 if (Mode == rtl_Cipher_ModeInvalid)
1009 return nullptr;
1010 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1011 if (Mode != rtl_Cipher_ModeStream) {
1012 // Cannot easily support ModeECB and ModeCBC, and they aren't used in the LO code at least:
1013 return nullptr;
1015 #endif
1017 pImpl = static_cast<CipherBF_Impl*>(rtl_allocateZeroMemory(sizeof (CipherBF_Impl)));
1018 if (pImpl)
1020 pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmBF;
1021 pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1022 pImpl->m_cipher.m_mode = Mode;
1024 pImpl->m_cipher.m_init = rtl_cipher_initBF;
1025 pImpl->m_cipher.m_encode = rtl_cipher_encodeBF;
1026 pImpl->m_cipher.m_decode = rtl_cipher_decodeBF;
1027 pImpl->m_cipher.m_delete = rtl_cipher_destroyBF;
1029 return static_cast<rtlCipher>(pImpl);
1032 rtlCipherError SAL_CALL rtl_cipher_initBF(
1033 rtlCipher Cipher,
1034 rtlCipherDirection Direction,
1035 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1036 const sal_uInt8 *pArgData, sal_Size nArgLen) SAL_THROW_EXTERN_C()
1038 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1040 if (!pImpl || !pKeyData)
1041 return rtl_Cipher_E_Argument;
1043 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1044 return rtl_Cipher_E_Algorithm;
1046 if (Direction != rtl_Cipher_DirectionInvalid)
1047 pImpl->m_cipher.m_direction = Direction;
1048 else
1049 return rtl_Cipher_E_Direction;
1051 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1052 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionBoth) {
1053 // Cannot easily support DirectionBoth, and it isn't used in the LO code at least:
1054 return rtl_Cipher_E_Direction;
1056 if (nKeyLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1057 return rtl_Cipher_E_BufferSize;
1059 if (pImpl->m_context.m_context != nullptr) {
1060 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1062 pImpl->m_context.m_context = EVP_CIPHER_CTX_new();
1063 if (pImpl->m_context.m_context == nullptr) {
1064 return rtl_Cipher_E_Memory;
1066 unsigned char iv[8];
1067 auto const n = std::min(nArgLen, sal_Size(8));
1068 std::memcpy(iv, pArgData, n);
1069 std::memset(iv + n, 0, 8 - n);
1070 if (EVP_CipherInit_ex(
1071 pImpl->m_context.m_context, EVP_bf_cfb(), nullptr, nullptr, iv,
1072 pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode ? 0 : 1)
1073 == 0)
1075 return rtl_Cipher_E_Unknown;
1077 if (EVP_CIPHER_CTX_set_key_length(pImpl->m_context.m_context, static_cast<int>(nKeyLen)) == 0) {
1078 return rtl_Cipher_E_Unknown;
1080 if (EVP_CipherInit_ex(pImpl->m_context.m_context, nullptr, nullptr, pKeyData, nullptr, -1) == 0)
1082 return rtl_Cipher_E_Unknown;
1084 return rtl_Cipher_E_None;
1085 #else
1086 return BF_init(
1087 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1088 pKeyData, nKeyLen, pArgData, nArgLen);
1089 #endif
1092 rtlCipherError SAL_CALL rtl_cipher_encodeBF(
1093 rtlCipher Cipher,
1094 const void *pData, sal_Size nDatLen,
1095 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1097 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1098 if (!pImpl)
1099 return rtl_Cipher_E_Argument;
1101 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1102 return rtl_Cipher_E_Algorithm;
1104 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1105 return rtl_Cipher_E_Direction;
1107 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode)
1108 return rtl_Cipher_E_Direction;
1110 return BF_update(
1111 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1112 rtl_Cipher_DirectionEncode,
1113 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1116 rtlCipherError SAL_CALL rtl_cipher_decodeBF(
1117 rtlCipher Cipher,
1118 const void *pData, sal_Size nDatLen,
1119 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1121 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1122 if (!pImpl)
1123 return rtl_Cipher_E_Argument;
1125 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1126 return rtl_Cipher_E_Algorithm;
1128 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1129 return rtl_Cipher_E_Direction;
1131 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionEncode)
1132 return rtl_Cipher_E_Direction;
1134 return BF_update(
1135 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1136 rtl_Cipher_DirectionDecode,
1137 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1140 void SAL_CALL rtl_cipher_destroyBF(rtlCipher Cipher) SAL_THROW_EXTERN_C()
1142 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1143 if (!pImpl)
1144 return;
1146 if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmBF)
1148 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1149 if (pImpl->m_context.m_context != nullptr) {
1150 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1152 #endif
1153 rtl_freeZeroMemory(pImpl, sizeof(CipherBF_Impl));
1155 else
1156 free(pImpl);
1159 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
1160 #define CIPHER_CBLOCK_ARCFOUR 256
1161 #endif
1163 namespace {
1165 struct ContextARCFOUR_Impl
1167 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1168 EVP_CIPHER_CTX * m_context;
1169 #else
1170 unsigned int m_S[CIPHER_CBLOCK_ARCFOUR];
1171 unsigned int m_X, m_Y;
1172 #endif
1175 struct CipherARCFOUR_Impl
1177 Cipher_Impl m_cipher;
1178 ContextARCFOUR_Impl m_context;
1183 static rtlCipherError rtl_cipherARCFOUR_update_Impl(
1184 ContextARCFOUR_Impl *ctx,
1185 const sal_uInt8 *pData, sal_Size nDatLen,
1186 sal_uInt8 *pBuffer, sal_Size nBufLen);
1188 static rtlCipherError rtl_cipherARCFOUR_init_Impl(
1189 ContextARCFOUR_Impl *ctx,
1190 const sal_uInt8 *pKeyData, sal_Size nKeyLen)
1192 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1193 if (nKeyLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1194 return rtl_Cipher_E_BufferSize;
1196 if (ctx->m_context != nullptr) {
1197 EVP_CIPHER_CTX_free(ctx->m_context);
1199 ctx->m_context = EVP_CIPHER_CTX_new();
1200 if (ctx->m_context == nullptr) {
1201 return rtl_Cipher_E_Memory;
1203 if (EVP_CipherInit_ex(ctx->m_context, EVP_rc4(), nullptr, nullptr, nullptr, 0) == 0) {
1204 // RC4 en- and decryption is identical, so we can use 0=decrypt regardless of direction,
1205 // and thus also support rtl_Cipher_DirectionBoth
1206 return rtl_Cipher_E_Unknown;
1208 if (EVP_CIPHER_CTX_set_key_length(ctx->m_context, static_cast<int>(nKeyLen)) == 0) {
1209 return rtl_Cipher_E_Unknown;
1211 if (EVP_CipherInit_ex(ctx->m_context, nullptr, nullptr, pKeyData, nullptr, -1) == 0) {
1212 return rtl_Cipher_E_Unknown;
1214 #else
1215 unsigned int K[CIPHER_CBLOCK_ARCFOUR];
1216 unsigned int *L, *S;
1217 unsigned int x, y;
1218 sal_Size n, k;
1220 S = &(ctx->m_S[0]);
1222 /* Initialize S linearly. */
1223 for (x = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1224 S[x] = x;
1226 /* Initialize K with key, repeat key as necessary. */
1227 for (L = K, n = CIPHER_CBLOCK_ARCFOUR; n > nKeyLen; n -= nKeyLen)
1229 for (k = 0; k < nKeyLen; k++)
1231 L[k] = pKeyData[k];
1234 L += nKeyLen;
1237 for (k = 0; k < n; k++)
1239 L[k] = pKeyData[k];
1242 /* Initialize S with K. */
1243 for (x = 0, y = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1245 y = (y + S[x] + K[x]) % CIPHER_CBLOCK_ARCFOUR;
1246 /* swap S[x] and S[y] */
1247 unsigned int t = S[x];
1248 S[x] = S[y];
1249 S[y] = t;
1252 /* Initialize counters X and Y. */
1253 ctx->m_X = 0;
1254 ctx->m_Y = 0;
1255 #endif
1257 return rtl_Cipher_E_None;
1260 static rtlCipherError rtl_cipherARCFOUR_update_Impl(
1261 ContextARCFOUR_Impl *ctx,
1262 const sal_uInt8 *pData, sal_Size nDatLen,
1263 sal_uInt8 *pBuffer, sal_Size nBufLen)
1265 /* Check arguments. */
1266 if (!pData || !pBuffer)
1267 return rtl_Cipher_E_Argument;
1269 if ((0 >= nDatLen) || (nDatLen > nBufLen))
1270 return rtl_Cipher_E_BufferSize;
1272 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1273 while (nDatLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1274 int outl;
1275 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, std::numeric_limits<int>::max())
1276 == 0)
1278 return rtl_Cipher_E_Unknown;
1280 assert(outl == std::numeric_limits<int>::max());
1281 pData += std::numeric_limits<int>::max();
1282 nDatLen -= std::numeric_limits<int>::max();
1283 pBuffer += std::numeric_limits<int>::max();
1285 int outl;
1286 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, static_cast<int>(nDatLen)) == 0) {
1287 return rtl_Cipher_E_Unknown;
1289 assert(outl == static_cast<int>(nDatLen));
1290 // A final call to EVP_CipherFinal_ex is intentionally missing; it wouldn't fit the rtl/cipher.h
1291 // interface, and is hopefully not needed, as each individual RC4 update step doesn't hold back
1292 // any data that would need to be finally flushed.
1293 #else
1294 unsigned int *S;
1295 sal_Size k;
1297 /* Update. */
1298 S = &(ctx->m_S[0]);
1299 for (k = 0; k < nDatLen; k++)
1301 /* Update counters X and Y. */
1302 unsigned int x = ctx->m_X;
1303 unsigned int y = ctx->m_Y;
1304 x = (x + 1 ) % CIPHER_CBLOCK_ARCFOUR;
1305 y = (y + S[x]) % CIPHER_CBLOCK_ARCFOUR;
1306 ctx->m_X = x;
1307 ctx->m_Y = y;
1309 /* Swap S[x] and S[y]. */
1310 unsigned int t = S[x];
1311 S[x] = S[y];
1312 S[y] = t;
1314 /* Evaluate next key byte S[t]. */
1315 t = (S[x] + S[y]) % CIPHER_CBLOCK_ARCFOUR;
1316 pBuffer[k] = pData[k] ^ static_cast<sal_uInt8>(S[t] & 0xff);
1318 #endif
1320 return rtl_Cipher_E_None;
1324 rtl_cipher_ARCFOUR (RC4) implementation.
1326 Reference: Bruce Schneier: Applied Cryptography, 2nd edition, ch. 17.1
1328 rtlCipher SAL_CALL rtl_cipher_createARCFOUR(rtlCipherMode Mode)
1329 SAL_THROW_EXTERN_C()
1331 CipherARCFOUR_Impl *pImpl = nullptr;
1333 if (Mode != rtl_Cipher_ModeStream)
1334 return nullptr;
1336 pImpl = static_cast<CipherARCFOUR_Impl*>(rtl_allocateZeroMemory(sizeof(CipherARCFOUR_Impl)));
1337 if (pImpl)
1339 pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmARCFOUR;
1340 pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1341 pImpl->m_cipher.m_mode = rtl_Cipher_ModeStream;
1343 pImpl->m_cipher.m_init = rtl_cipher_initARCFOUR;
1344 pImpl->m_cipher.m_encode = rtl_cipher_encodeARCFOUR;
1345 pImpl->m_cipher.m_decode = rtl_cipher_decodeARCFOUR;
1346 pImpl->m_cipher.m_delete = rtl_cipher_destroyARCFOUR;
1349 return static_cast<rtlCipher>(pImpl);
1352 rtlCipherError SAL_CALL rtl_cipher_initARCFOUR(
1353 rtlCipher Cipher,
1354 rtlCipherDirection Direction,
1355 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1356 SAL_UNUSED_PARAMETER const sal_uInt8 *, SAL_UNUSED_PARAMETER sal_Size)
1357 SAL_THROW_EXTERN_C()
1359 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1361 if (!pImpl || !pKeyData)
1362 return rtl_Cipher_E_Argument;
1364 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1365 return rtl_Cipher_E_Algorithm;
1367 if (Direction != rtl_Cipher_DirectionInvalid)
1368 pImpl->m_cipher.m_direction = Direction;
1369 else
1370 return rtl_Cipher_E_Direction;
1372 return rtl_cipherARCFOUR_init_Impl(&(pImpl->m_context), pKeyData, nKeyLen);
1375 rtlCipherError SAL_CALL rtl_cipher_encodeARCFOUR(
1376 rtlCipher Cipher,
1377 const void *pData, sal_Size nDatLen,
1378 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1380 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1381 if (!pImpl)
1382 return rtl_Cipher_E_Argument;
1384 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1385 return rtl_Cipher_E_Algorithm;
1387 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1388 return rtl_Cipher_E_Direction;
1390 return rtl_cipherARCFOUR_update_Impl(
1391 &(pImpl->m_context),
1392 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1395 rtlCipherError SAL_CALL rtl_cipher_decodeARCFOUR(
1396 rtlCipher Cipher,
1397 const void *pData, sal_Size nDatLen,
1398 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1400 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1401 if (!pImpl)
1402 return rtl_Cipher_E_Argument;
1404 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1405 return rtl_Cipher_E_Algorithm;
1407 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1408 return rtl_Cipher_E_Direction;
1410 return rtl_cipherARCFOUR_update_Impl(
1411 &(pImpl->m_context),
1412 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1415 void SAL_CALL rtl_cipher_destroyARCFOUR(rtlCipher Cipher) SAL_THROW_EXTERN_C()
1417 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1418 if (!pImpl)
1419 return;
1421 if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmARCFOUR)
1423 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1424 if (pImpl->m_context.m_context != nullptr) {
1425 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1427 #endif
1428 rtl_freeZeroMemory(pImpl, sizeof(CipherARCFOUR_Impl));
1430 else
1431 free(pImpl);
1434 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */