Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sal / rtl / cipher.cxx
blobbb0884b7a3d616805fc22560d55ec0070ff2b697
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 <o3tl/safeint.hxx>
23 #include <sal/types.h>
24 #include <rtl/alloc.h>
25 #include <rtl/cipher.h>
26 #include <algorithm>
27 #include <cassert>
28 #include <cstring>
29 #include <limits>
31 #if defined LIBO_CIPHER_OPENSSL_BACKEND
32 #include <openssl/evp.h>
33 #endif
35 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
36 #define RTL_CIPHER_NTOHL(c, l) \
37 ((l) = (static_cast<sal_uInt32>(*((c)++))) << 24, \
38 (l) |= (static_cast<sal_uInt32>(*((c)++))) << 16, \
39 (l) |= (static_cast<sal_uInt32>(*((c)++))) << 8, \
40 (l) |= (static_cast<sal_uInt32>(*((c)++))))
42 #define RTL_CIPHER_HTONL(l, c) \
43 (*((c)++) = static_cast<sal_uInt8>(((l) >> 24) & 0xff), \
44 *((c)++) = static_cast<sal_uInt8>(((l) >> 16) & 0xff), \
45 *((c)++) = static_cast<sal_uInt8>(((l) >> 8) & 0xff), \
46 *((c)++) = static_cast<sal_uInt8>(((l) ) & 0xff))
48 #define RTL_CIPHER_NTOHL64(c, xl, xr, n) \
49 { \
50 (xl) = (xr) = 0; \
51 (c) += (n); \
52 switch ((n)) \
53 { \
54 case 8: (xr) = (static_cast<sal_uInt32>(*(--(c)))); \
55 [[fallthrough]]; \
56 case 7: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 8; \
57 [[fallthrough]]; \
58 case 6: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 16; \
59 [[fallthrough]]; \
60 case 5: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 24; \
61 [[fallthrough]]; \
62 case 4: (xl) = (static_cast<sal_uInt32>(*(--(c)))); \
63 [[fallthrough]]; \
64 case 3: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 8; \
65 [[fallthrough]]; \
66 case 2: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 16; \
67 [[fallthrough]]; \
68 case 1: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 24; \
69 } \
72 #define RTL_CIPHER_HTONL64(xl, xr, c, n) \
73 { \
74 (c) += (n); \
75 switch ((n)) \
76 { \
77 case 8: *(--(c)) = static_cast<sal_uInt8>(((xr) ) & 0xff); \
78 [[fallthrough]]; \
79 case 7: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 8) & 0xff); \
80 [[fallthrough]]; \
81 case 6: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 16) & 0xff); \
82 [[fallthrough]]; \
83 case 5: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 24) & 0xff); \
84 [[fallthrough]]; \
85 case 4: *(--(c)) = static_cast<sal_uInt8>(((xl) ) & 0xff); \
86 [[fallthrough]]; \
87 case 3: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 8) & 0xff); \
88 [[fallthrough]]; \
89 case 2: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 16) & 0xff); \
90 [[fallthrough]]; \
91 case 1: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 24) & 0xff); \
92 } \
94 #endif
96 typedef rtlCipherError(cipher_init_t) (
97 rtlCipher Cipher,
98 rtlCipherDirection Direction,
99 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
100 const sal_uInt8 *pArgData, sal_Size nArgLen);
102 typedef rtlCipherError(cipher_update_t) (
103 rtlCipher Cipher,
104 const void *pData, sal_Size nDatLen,
105 sal_uInt8 *pBuffer, sal_Size nBufLen);
107 typedef void (cipher_delete_t) (rtlCipher Cipher);
109 namespace {
111 struct Cipher_Impl
113 rtlCipherAlgorithm m_algorithm;
114 rtlCipherDirection m_direction;
115 rtlCipherMode m_mode;
117 cipher_init_t *m_init;
118 cipher_update_t *m_encode;
119 cipher_update_t *m_decode;
120 cipher_delete_t *m_delete;
125 rtlCipher SAL_CALL rtl_cipher_create(
126 rtlCipherAlgorithm Algorithm,
127 rtlCipherMode Mode) SAL_THROW_EXTERN_C()
129 rtlCipher Cipher = nullptr;
130 switch (Algorithm)
132 case rtl_Cipher_AlgorithmBF:
133 Cipher = rtl_cipher_createBF (Mode);
134 break;
136 case rtl_Cipher_AlgorithmARCFOUR:
137 Cipher = rtl_cipher_createARCFOUR (Mode);
138 break;
140 default: /* rtl_Cipher_AlgorithmInvalid */
141 break;
143 return Cipher;
146 rtlCipherError SAL_CALL rtl_cipher_init(
147 rtlCipher Cipher,
148 rtlCipherDirection Direction,
149 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
150 const sal_uInt8 *pArgData, sal_Size nArgLen) SAL_THROW_EXTERN_C()
152 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
153 if (!pImpl)
154 return rtl_Cipher_E_Argument;
156 if (!pImpl->m_init)
157 return rtl_Cipher_E_Unknown;
159 return (pImpl->m_init)(
160 Cipher, Direction, pKeyData, nKeyLen, pArgData, nArgLen);
163 rtlCipherError SAL_CALL rtl_cipher_encode(
164 rtlCipher Cipher,
165 const void *pData, sal_Size nDatLen,
166 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
168 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
169 if (!pImpl)
170 return rtl_Cipher_E_Argument;
172 if (!pImpl->m_encode)
173 return rtl_Cipher_E_Unknown;
175 return (pImpl->m_encode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
178 rtlCipherError SAL_CALL rtl_cipher_decode(
179 rtlCipher Cipher,
180 const void *pData, sal_Size nDatLen,
181 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
183 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
184 if (!pImpl)
185 return rtl_Cipher_E_Argument;
187 if (!pImpl->m_decode)
188 return rtl_Cipher_E_Unknown;
190 return (pImpl->m_decode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
193 void SAL_CALL rtl_cipher_destroy(rtlCipher Cipher) SAL_THROW_EXTERN_C()
195 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
196 if (pImpl && pImpl->m_delete)
197 pImpl->m_delete(Cipher);
200 namespace {
202 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
203 #define CIPHER_ROUNDS_BF 16
205 struct CipherKeyBF
207 sal_uInt32 m_S[4][256];
208 sal_uInt32 m_P[CIPHER_ROUNDS_BF + 2];
210 #endif
212 struct CipherContextBF
214 #if defined LIBO_CIPHER_OPENSSL_BACKEND
215 EVP_CIPHER_CTX * m_context;
216 #else
217 CipherKeyBF m_key;
218 union
220 sal_uInt32 m_long[2];
221 sal_uInt8 m_byte[8];
222 } m_iv;
223 sal_uInt32 m_offset;
224 #endif
227 struct CipherBF_Impl
229 Cipher_Impl m_cipher;
230 CipherContextBF m_context;
235 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
236 static rtlCipherError BF_init(
237 CipherContextBF *ctx,
238 rtlCipherMode eMode,
239 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
240 const sal_uInt8 *pArgData, sal_Size nArgLen);
241 #endif
243 static rtlCipherError BF_update(
244 CipherContextBF *ctx,
245 rtlCipherMode eMode,
246 rtlCipherDirection eDirection,
247 const sal_uInt8 *pData, sal_Size nDatLen,
248 sal_uInt8 *pBuffer, sal_Size nBufLen);
250 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
251 static void BF_updateECB(
252 CipherContextBF *ctx,
253 rtlCipherDirection direction,
254 const sal_uInt8 *pData,
255 sal_uInt8 *pBuffer,
256 sal_Size nLength);
258 static void BF_updateCBC(
259 CipherContextBF *ctx,
260 rtlCipherDirection direction,
261 const sal_uInt8 *pData,
262 sal_uInt8 *pBuffer,
263 sal_Size nLength);
265 static void BF_updateCFB(
266 CipherContextBF *ctx,
267 rtlCipherDirection direction,
268 const sal_uInt8 *pData,
269 sal_uInt8 *pBuffer);
271 static void BF_encode(CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
273 static void BF_decode(CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
275 static sal_uInt32 BF(CipherKeyBF *key, sal_uInt32 x);
277 const CipherKeyBF BF_key =
279 /* S */
281 /* S[0] */
283 /* 0 */
284 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
285 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
286 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
287 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
289 /* 1 */
290 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
291 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
292 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
293 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
295 /* 2 */
296 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
297 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
298 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
299 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
301 /* 3 */
302 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
303 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
304 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
305 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
307 /* 4 */
308 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
309 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
310 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
311 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
313 /* 5 */
314 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
315 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
316 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
317 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
319 /* 6 */
320 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
321 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
322 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
323 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
325 /* 7 */
326 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
327 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
328 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
329 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
331 /* 8 */
332 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
333 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
334 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
335 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
337 /* 9 */
338 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
339 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
340 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
341 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
343 /* A */
344 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
345 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
346 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
347 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
349 /* B */
350 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
351 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
352 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
353 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
355 /* C */
356 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
357 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
358 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
359 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
361 /* D */
362 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
363 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
364 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
365 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
367 /* E */
368 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
369 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
370 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
371 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
373 /* F */
374 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
375 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
376 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
377 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL
380 /* S[1] */
382 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
383 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
384 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
385 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
387 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
388 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
389 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
390 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
392 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
393 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
394 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
395 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
397 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
398 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
399 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
400 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
402 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
403 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
404 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
405 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
407 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
408 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
409 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
410 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
412 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
413 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
414 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
415 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
417 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
418 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
419 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
420 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
422 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
423 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
424 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
425 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
427 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
428 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
429 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
430 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
432 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
433 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
434 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
435 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
437 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
438 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
439 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
440 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
442 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
443 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
444 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
445 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
447 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
448 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
449 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
450 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
452 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
453 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
454 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
455 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
457 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
458 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
459 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
460 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L
463 /* S[2] */
465 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
466 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
467 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
468 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
470 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
471 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
472 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
473 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
475 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
476 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
477 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
478 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
480 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
481 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
482 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
483 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
485 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
486 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
487 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
488 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
490 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
491 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
492 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
493 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
495 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
496 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
497 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
498 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
500 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
501 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
502 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
503 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
505 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
506 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
507 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
508 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
510 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
511 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
512 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
513 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
515 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
516 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
517 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
518 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
520 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
521 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
522 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
523 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
525 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
526 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
527 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
528 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
530 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
531 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
532 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
533 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
535 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
536 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
537 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
538 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
540 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
541 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
542 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
543 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L
546 /* S[3] */
548 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
549 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
550 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
551 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
553 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
554 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
555 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
556 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
558 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
559 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
560 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
561 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
563 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
564 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
565 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
566 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
568 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
569 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
570 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
571 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
573 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
574 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
575 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
576 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
578 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
579 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
580 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
581 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
583 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
584 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
585 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
586 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
588 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
589 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
590 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
591 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
593 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
594 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
595 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
596 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
598 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
599 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
600 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
601 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
603 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
604 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
605 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
606 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
608 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
609 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
610 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
611 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
613 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
614 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
615 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
616 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
618 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
619 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
620 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
621 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
623 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
624 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
625 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
626 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L
630 /* P */
632 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
633 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
634 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
635 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
636 0x9216D5D9L, 0x8979FB1BL
639 #endif
641 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
642 static rtlCipherError BF_init(
643 CipherContextBF *ctx,
644 rtlCipherMode eMode,
645 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
646 const sal_uInt8 *pArgData, sal_Size nArgLen)
648 CipherKeyBF *key;
649 sal_uInt32 D, DL, DR;
650 sal_uInt16 i, j, k;
652 key = &(ctx->m_key);
654 memcpy(key, &BF_key, sizeof (CipherKeyBF));
655 memset(&(ctx->m_iv), 0, sizeof(ctx->m_iv));
656 ctx->m_offset = 0;
658 for (i = 0, k = 0; i < CIPHER_ROUNDS_BF + 2; ++i)
660 D = 0;
661 for (j = 0; j < 4; ++j)
663 D = ((D << 8) | pKeyData[k]);
664 k++;
665 if (k >= nKeyLen)
666 k = 0;
668 key->m_P[i] ^= D;
671 rtl_secureZeroMemory(&DL, sizeof(DL));
672 rtl_secureZeroMemory(&DR, sizeof(DR));
674 for (i = 0; i < CIPHER_ROUNDS_BF + 2; i += 2)
676 BF_encode(key, &DL, &DR);
677 key->m_P[i ] = DL;
678 key->m_P[i + 1] = DR;
681 for (i = 0; i < 4; ++i)
683 for (k = 0; k < 256; k += 2)
685 BF_encode(key, &DL, &DR);
686 key->m_S[i][k ] = DL;
687 key->m_S[i][k + 1] = DR;
691 if (pArgData && nArgLen)
693 nArgLen = std::min<sal_Size>(nArgLen, 8);
694 if (eMode == rtl_Cipher_ModeStream)
696 memcpy(ctx->m_iv.m_byte, pArgData, nArgLen);
698 else
700 RTL_CIPHER_NTOHL64 (pArgData, DL, DR, nArgLen);
701 ctx->m_iv.m_long[0] = DL;
702 ctx->m_iv.m_long[1] = DR;
706 return rtl_Cipher_E_None;
708 #endif
710 static rtlCipherError BF_update(
711 CipherContextBF *ctx,
712 rtlCipherMode eMode,
713 rtlCipherDirection eDirection,
714 const sal_uInt8 *pData, sal_Size nDatLen,
715 sal_uInt8 *pBuffer, sal_Size nBufLen)
717 /* Check arguments. */
718 if (!pData || !pBuffer)
719 return rtl_Cipher_E_Argument;
721 if ((nDatLen <= 0) || (nDatLen > nBufLen))
722 return rtl_Cipher_E_BufferSize;
724 /* Update. */
725 #if defined LIBO_CIPHER_OPENSSL_BACKEND
726 assert(eMode == rtl_Cipher_ModeStream);
727 (void) eMode;
728 (void) eDirection;
729 while (nDatLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
730 int outl;
731 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, std::numeric_limits<int>::max())
732 == 0)
734 return rtl_Cipher_E_Unknown;
736 assert(outl == std::numeric_limits<int>::max());
737 pData += std::numeric_limits<int>::max();
738 nDatLen -= std::numeric_limits<int>::max();
739 pBuffer += std::numeric_limits<int>::max();
741 int outl;
742 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, static_cast<int>(nDatLen)) == 0)
744 return rtl_Cipher_E_Unknown;
746 assert(outl == static_cast<int>(nDatLen));
747 // A final call to EVP_CipherFinal_ex is intentionally missing; it wouldn't fit the rtl/cipher.h
748 // interface, and is hopefully not needed, as each individual Blowfish CFB update step doesn't
749 // hold back any data that would need to be finally flushed.
750 #else
751 if (eMode == rtl_Cipher_ModeECB)
753 /* Block mode. */
754 while (nDatLen > 8)
756 BF_updateECB(ctx, eDirection, pData, pBuffer, 8);
757 nDatLen -= 8;
758 pData += 8;
759 pBuffer += 8;
761 BF_updateECB(ctx, eDirection, pData, pBuffer, nDatLen);
763 else if (eMode == rtl_Cipher_ModeCBC)
765 /* Block mode. */
766 while (nDatLen > 8)
768 BF_updateCBC (ctx, eDirection, pData, pBuffer, 8);
769 nDatLen -= 8;
770 pData += 8;
771 pBuffer += 8;
773 BF_updateCBC (ctx, eDirection, pData, pBuffer, nDatLen);
775 else
777 /* Stream mode. */
778 while (nDatLen > 0)
780 BF_updateCFB (ctx, eDirection, pData, pBuffer);
781 nDatLen -= 1;
782 pData += 1;
783 pBuffer += 1;
786 #endif
787 return rtl_Cipher_E_None;
790 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
791 static void BF_updateECB(
792 CipherContextBF *ctx,
793 rtlCipherDirection direction,
794 const sal_uInt8 *pData,
795 sal_uInt8 *pBuffer,
796 sal_Size nLength)
798 CipherKeyBF *key;
799 sal_uInt32 DL, DR;
801 key = &(ctx->m_key);
802 if (direction == rtl_Cipher_DirectionEncode)
804 RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
806 BF_encode(key, &DL, &DR);
808 RTL_CIPHER_HTONL(DL, pBuffer);
809 RTL_CIPHER_HTONL(DR, pBuffer);
811 else
813 RTL_CIPHER_NTOHL(pData, DL);
814 RTL_CIPHER_NTOHL(pData, DR);
816 BF_decode(key, &DL, &DR);
818 RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
820 rtl_secureZeroMemory(&DL, sizeof(DL));
821 rtl_secureZeroMemory(&DR, sizeof(DR));
824 static void BF_updateCBC(
825 CipherContextBF *ctx,
826 rtlCipherDirection direction,
827 const sal_uInt8 *pData,
828 sal_uInt8 *pBuffer,
829 sal_Size nLength)
831 CipherKeyBF *key;
832 sal_uInt32 DL, DR;
834 key = &(ctx->m_key);
835 if (direction == rtl_Cipher_DirectionEncode)
837 RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
839 DL ^= ctx->m_iv.m_long[0];
840 DR ^= ctx->m_iv.m_long[1];
842 BF_encode(key, &DL, &DR);
844 ctx->m_iv.m_long[0] = DL;
845 ctx->m_iv.m_long[1] = DR;
847 RTL_CIPHER_HTONL(DL, pBuffer);
848 RTL_CIPHER_HTONL(DR, pBuffer);
850 else
852 sal_uInt32 IVL, IVR;
854 RTL_CIPHER_NTOHL(pData, DL);
855 RTL_CIPHER_NTOHL(pData, DR);
857 IVL = DL;
858 IVR = DR;
860 BF_decode(key, &DL, &DR);
862 DL ^= ctx->m_iv.m_long[0];
863 DR ^= ctx->m_iv.m_long[1];
865 ctx->m_iv.m_long[0] = IVL;
866 ctx->m_iv.m_long[1] = IVR;
868 RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
870 rtl_secureZeroMemory(&DL, sizeof(DL));
871 rtl_secureZeroMemory(&DR, sizeof(DR));
874 static void BF_updateCFB(
875 CipherContextBF *ctx,
876 rtlCipherDirection direction,
877 const sal_uInt8 *pData,
878 sal_uInt8 *pBuffer)
880 sal_uInt8 *iv;
881 sal_uInt32 k;
883 iv = ctx->m_iv.m_byte;
884 k = ctx->m_offset;
886 if (k == 0)
888 sal_uInt32 IVL, IVR;
890 RTL_CIPHER_NTOHL64(iv, IVL, IVR, 8);
891 BF_encode(&(ctx->m_key), &IVL, &IVR);
892 RTL_CIPHER_HTONL64(IVL, IVR, iv, 8);
894 rtl_secureZeroMemory(&IVL, sizeof(IVL));
895 rtl_secureZeroMemory(&IVR, sizeof(IVR));
898 if (direction == rtl_Cipher_DirectionEncode)
900 iv[k] ^= *pData;
901 *pBuffer = iv[k];
903 else
905 sal_uInt8 c = iv[k];
906 iv[k] = *pData;
907 *pBuffer = *pData ^ c;
910 ctx->m_offset = ((k + 1) & 0x07);
911 iv = nullptr;
914 static void BF_encode(
915 CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
917 sal_uInt32 t, XL, XR;
918 sal_uInt16 i;
920 XL = *xl;
921 XR = *xr;
923 for (i = 0; i < CIPHER_ROUNDS_BF; ++i)
925 XL ^= key->m_P[i];
926 XR ^= BF (key, XL);
928 t = XL;
929 XL = XR;
930 XR = t;
933 t = XL;
934 XL = XR;
935 XR = t;
937 XR ^= key->m_P[CIPHER_ROUNDS_BF ];
938 XL ^= key->m_P[CIPHER_ROUNDS_BF + 1];
940 *xl = XL;
941 *xr = XR;
945 static void BF_decode(
946 CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
948 sal_uInt32 t, XL, XR;
949 sal_uInt16 i;
951 XL = *xl;
952 XR = *xr;
954 for (i = CIPHER_ROUNDS_BF + 1; i > 1; --i)
956 XL ^= key->m_P[i];
957 XR ^= BF (key, XL);
959 t = XL;
960 XL = XR;
961 XR = t;
964 t = XL;
965 XL = XR;
966 XR = t;
968 XR ^= key->m_P[1];
969 XL ^= key->m_P[0];
971 *xl = XL;
972 *xr = XR;
976 static sal_uInt32 BF(CipherKeyBF *key, sal_uInt32 x)
978 sal_uInt16 a, b, c, d;
979 sal_uInt32 y;
981 d = static_cast<sal_uInt16>(x & 0x00ff);
982 x >>= 8;
983 c = static_cast<sal_uInt16>(x & 0x00ff);
984 x >>= 8;
985 b = static_cast<sal_uInt16>(x & 0x00ff);
986 x >>= 8;
987 a = static_cast<sal_uInt16>(x & 0x00ff);
989 y = key->m_S[0][a];
990 y += key->m_S[1][b];
991 y ^= key->m_S[2][c];
992 y += key->m_S[3][d];
994 return y;
996 #endif
999 rtl_cipherBF (Blowfish) implementation.
1001 Reference: Bruce Schneier: Applied Cryptography, 2nd edition, ch. 14.3
1003 rtlCipher SAL_CALL rtl_cipher_createBF(rtlCipherMode Mode) SAL_THROW_EXTERN_C()
1005 CipherBF_Impl *pImpl = nullptr;
1007 if (Mode == rtl_Cipher_ModeInvalid)
1008 return nullptr;
1009 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1010 if (Mode != rtl_Cipher_ModeStream) {
1011 // Cannot easily support ModeECB and ModeCBC, and they aren't used in the LO code at least:
1012 return nullptr;
1014 #endif
1016 pImpl = static_cast<CipherBF_Impl*>(rtl_allocateZeroMemory(sizeof (CipherBF_Impl)));
1017 if (pImpl)
1019 pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmBF;
1020 pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1021 pImpl->m_cipher.m_mode = Mode;
1023 pImpl->m_cipher.m_init = rtl_cipher_initBF;
1024 pImpl->m_cipher.m_encode = rtl_cipher_encodeBF;
1025 pImpl->m_cipher.m_decode = rtl_cipher_decodeBF;
1026 pImpl->m_cipher.m_delete = rtl_cipher_destroyBF;
1028 return static_cast<rtlCipher>(pImpl);
1031 rtlCipherError SAL_CALL rtl_cipher_initBF(
1032 rtlCipher Cipher,
1033 rtlCipherDirection Direction,
1034 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1035 const sal_uInt8 *pArgData, sal_Size nArgLen) SAL_THROW_EXTERN_C()
1037 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1039 if (!pImpl || !pKeyData)
1040 return rtl_Cipher_E_Argument;
1042 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1043 return rtl_Cipher_E_Algorithm;
1045 if (Direction != rtl_Cipher_DirectionInvalid)
1046 pImpl->m_cipher.m_direction = Direction;
1047 else
1048 return rtl_Cipher_E_Direction;
1050 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1051 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionBoth) {
1052 // Cannot easily support DirectionBoth, and it isn't used in the LO code at least:
1053 return rtl_Cipher_E_Direction;
1055 if (nKeyLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1056 return rtl_Cipher_E_BufferSize;
1058 if (pImpl->m_context.m_context != nullptr) {
1059 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1061 pImpl->m_context.m_context = EVP_CIPHER_CTX_new();
1062 if (pImpl->m_context.m_context == nullptr) {
1063 return rtl_Cipher_E_Memory;
1065 unsigned char iv[8];
1066 auto const n = std::min(nArgLen, sal_Size(8));
1067 std::memcpy(iv, pArgData, n);
1068 std::memset(iv + n, 0, 8 - n);
1069 if (EVP_CipherInit_ex(
1070 pImpl->m_context.m_context, EVP_bf_cfb(), nullptr, nullptr, iv,
1071 pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode ? 0 : 1)
1072 == 0)
1074 return rtl_Cipher_E_Unknown;
1076 if (EVP_CIPHER_CTX_set_key_length(pImpl->m_context.m_context, static_cast<int>(nKeyLen)) == 0) {
1077 return rtl_Cipher_E_Unknown;
1079 if (EVP_CipherInit_ex(pImpl->m_context.m_context, nullptr, nullptr, pKeyData, nullptr, -1) == 0)
1081 return rtl_Cipher_E_Unknown;
1083 return rtl_Cipher_E_None;
1084 #else
1085 return BF_init(
1086 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1087 pKeyData, nKeyLen, pArgData, nArgLen);
1088 #endif
1091 rtlCipherError SAL_CALL rtl_cipher_encodeBF(
1092 rtlCipher Cipher,
1093 const void *pData, sal_Size nDatLen,
1094 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1096 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1097 if (!pImpl)
1098 return rtl_Cipher_E_Argument;
1100 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1101 return rtl_Cipher_E_Algorithm;
1103 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1104 return rtl_Cipher_E_Direction;
1106 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode)
1107 return rtl_Cipher_E_Direction;
1109 return BF_update(
1110 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1111 rtl_Cipher_DirectionEncode,
1112 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1115 rtlCipherError SAL_CALL rtl_cipher_decodeBF(
1116 rtlCipher Cipher,
1117 const void *pData, sal_Size nDatLen,
1118 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1120 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1121 if (!pImpl)
1122 return rtl_Cipher_E_Argument;
1124 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1125 return rtl_Cipher_E_Algorithm;
1127 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1128 return rtl_Cipher_E_Direction;
1130 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionEncode)
1131 return rtl_Cipher_E_Direction;
1133 return BF_update(
1134 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1135 rtl_Cipher_DirectionDecode,
1136 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1139 void SAL_CALL rtl_cipher_destroyBF(rtlCipher Cipher) SAL_THROW_EXTERN_C()
1141 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1142 if (!pImpl)
1143 return;
1145 if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmBF)
1147 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1148 if (pImpl->m_context.m_context != nullptr) {
1149 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1151 #endif
1152 rtl_freeZeroMemory(pImpl, sizeof(CipherBF_Impl));
1154 else
1155 free(pImpl);
1158 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
1159 #define CIPHER_CBLOCK_ARCFOUR 256
1160 #endif
1162 namespace {
1164 struct ContextARCFOUR_Impl
1166 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1167 EVP_CIPHER_CTX * m_context;
1168 #else
1169 unsigned int m_S[CIPHER_CBLOCK_ARCFOUR];
1170 unsigned int m_X, m_Y;
1171 #endif
1174 struct CipherARCFOUR_Impl
1176 Cipher_Impl m_cipher;
1177 ContextARCFOUR_Impl m_context;
1182 static rtlCipherError rtl_cipherARCFOUR_update_Impl(
1183 ContextARCFOUR_Impl *ctx,
1184 const sal_uInt8 *pData, sal_Size nDatLen,
1185 sal_uInt8 *pBuffer, sal_Size nBufLen);
1187 static rtlCipherError rtl_cipherARCFOUR_init_Impl(
1188 ContextARCFOUR_Impl *ctx,
1189 const sal_uInt8 *pKeyData, sal_Size nKeyLen)
1191 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1192 if (nKeyLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1193 return rtl_Cipher_E_BufferSize;
1195 if (ctx->m_context != nullptr) {
1196 EVP_CIPHER_CTX_free(ctx->m_context);
1198 ctx->m_context = EVP_CIPHER_CTX_new();
1199 if (ctx->m_context == nullptr) {
1200 return rtl_Cipher_E_Memory;
1202 if (EVP_CipherInit_ex(ctx->m_context, EVP_rc4(), nullptr, nullptr, nullptr, 0) == 0) {
1203 // RC4 en- and decryption is identical, so we can use 0=decrypt regardless of direction,
1204 // and thus also support rtl_Cipher_DirectionBoth
1205 return rtl_Cipher_E_Unknown;
1207 if (EVP_CIPHER_CTX_set_key_length(ctx->m_context, static_cast<int>(nKeyLen)) == 0) {
1208 return rtl_Cipher_E_Unknown;
1210 if (EVP_CipherInit_ex(ctx->m_context, nullptr, nullptr, pKeyData, nullptr, -1) == 0) {
1211 return rtl_Cipher_E_Unknown;
1213 #else
1214 unsigned int K[CIPHER_CBLOCK_ARCFOUR];
1215 unsigned int *L, *S;
1216 unsigned int x, y;
1217 sal_Size n, k;
1219 S = &(ctx->m_S[0]);
1221 /* Initialize S linearly. */
1222 for (x = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1223 S[x] = x;
1225 /* Initialize K with key, repeat key as necessary. */
1226 for (L = K, n = CIPHER_CBLOCK_ARCFOUR; n > nKeyLen; n -= nKeyLen)
1228 for (k = 0; k < nKeyLen; k++)
1230 L[k] = pKeyData[k];
1233 L += nKeyLen;
1236 for (k = 0; k < n; k++)
1238 L[k] = pKeyData[k];
1241 /* Initialize S with K. */
1242 for (x = 0, y = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1244 y = (y + S[x] + K[x]) % CIPHER_CBLOCK_ARCFOUR;
1245 /* swap S[x] and S[y] */
1246 unsigned int t = S[x];
1247 S[x] = S[y];
1248 S[y] = t;
1251 /* Initialize counters X and Y. */
1252 ctx->m_X = 0;
1253 ctx->m_Y = 0;
1254 #endif
1256 return rtl_Cipher_E_None;
1259 static rtlCipherError rtl_cipherARCFOUR_update_Impl(
1260 ContextARCFOUR_Impl *ctx,
1261 const sal_uInt8 *pData, sal_Size nDatLen,
1262 sal_uInt8 *pBuffer, sal_Size nBufLen)
1264 /* Check arguments. */
1265 if (!pData || !pBuffer)
1266 return rtl_Cipher_E_Argument;
1268 if ((0 >= nDatLen) || (nDatLen > nBufLen))
1269 return rtl_Cipher_E_BufferSize;
1271 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1272 while (nDatLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1273 int outl;
1274 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, std::numeric_limits<int>::max())
1275 == 0)
1277 return rtl_Cipher_E_Unknown;
1279 assert(outl == std::numeric_limits<int>::max());
1280 pData += std::numeric_limits<int>::max();
1281 nDatLen -= std::numeric_limits<int>::max();
1282 pBuffer += std::numeric_limits<int>::max();
1284 int outl;
1285 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, static_cast<int>(nDatLen)) == 0) {
1286 return rtl_Cipher_E_Unknown;
1288 assert(outl == static_cast<int>(nDatLen));
1289 // A final call to EVP_CipherFinal_ex is intentionally missing; it wouldn't fit the rtl/cipher.h
1290 // interface, and is hopefully not needed, as each individual RC4 update step doesn't hold back
1291 // any data that would need to be finally flushed.
1292 #else
1293 unsigned int *S;
1294 sal_Size k;
1296 /* Update. */
1297 S = &(ctx->m_S[0]);
1298 for (k = 0; k < nDatLen; k++)
1300 /* Update counters X and Y. */
1301 unsigned int x = ctx->m_X;
1302 unsigned int y = ctx->m_Y;
1303 x = (x + 1 ) % CIPHER_CBLOCK_ARCFOUR;
1304 y = (y + S[x]) % CIPHER_CBLOCK_ARCFOUR;
1305 ctx->m_X = x;
1306 ctx->m_Y = y;
1308 /* Swap S[x] and S[y]. */
1309 unsigned int t = S[x];
1310 S[x] = S[y];
1311 S[y] = t;
1313 /* Evaluate next key byte S[t]. */
1314 t = (S[x] + S[y]) % CIPHER_CBLOCK_ARCFOUR;
1315 pBuffer[k] = pData[k] ^ static_cast<sal_uInt8>(S[t] & 0xff);
1317 #endif
1319 return rtl_Cipher_E_None;
1323 rtl_cipher_ARCFOUR (RC4) implementation.
1325 Reference: Bruce Schneier: Applied Cryptography, 2nd edition, ch. 17.1
1327 rtlCipher SAL_CALL rtl_cipher_createARCFOUR(rtlCipherMode Mode)
1328 SAL_THROW_EXTERN_C()
1330 CipherARCFOUR_Impl *pImpl = nullptr;
1332 if (Mode != rtl_Cipher_ModeStream)
1333 return nullptr;
1335 pImpl = static_cast<CipherARCFOUR_Impl*>(rtl_allocateZeroMemory(sizeof(CipherARCFOUR_Impl)));
1336 if (pImpl)
1338 pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmARCFOUR;
1339 pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1340 pImpl->m_cipher.m_mode = rtl_Cipher_ModeStream;
1342 pImpl->m_cipher.m_init = rtl_cipher_initARCFOUR;
1343 pImpl->m_cipher.m_encode = rtl_cipher_encodeARCFOUR;
1344 pImpl->m_cipher.m_decode = rtl_cipher_decodeARCFOUR;
1345 pImpl->m_cipher.m_delete = rtl_cipher_destroyARCFOUR;
1348 return static_cast<rtlCipher>(pImpl);
1351 rtlCipherError SAL_CALL rtl_cipher_initARCFOUR(
1352 rtlCipher Cipher,
1353 rtlCipherDirection Direction,
1354 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1355 SAL_UNUSED_PARAMETER const sal_uInt8 *, SAL_UNUSED_PARAMETER sal_Size)
1356 SAL_THROW_EXTERN_C()
1358 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1360 if (!pImpl || !pKeyData)
1361 return rtl_Cipher_E_Argument;
1363 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1364 return rtl_Cipher_E_Algorithm;
1366 if (Direction != rtl_Cipher_DirectionInvalid)
1367 pImpl->m_cipher.m_direction = Direction;
1368 else
1369 return rtl_Cipher_E_Direction;
1371 return rtl_cipherARCFOUR_init_Impl(&(pImpl->m_context), pKeyData, nKeyLen);
1374 rtlCipherError SAL_CALL rtl_cipher_encodeARCFOUR(
1375 rtlCipher Cipher,
1376 const void *pData, sal_Size nDatLen,
1377 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1379 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1380 if (!pImpl)
1381 return rtl_Cipher_E_Argument;
1383 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1384 return rtl_Cipher_E_Algorithm;
1386 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1387 return rtl_Cipher_E_Direction;
1389 return rtl_cipherARCFOUR_update_Impl(
1390 &(pImpl->m_context),
1391 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1394 rtlCipherError SAL_CALL rtl_cipher_decodeARCFOUR(
1395 rtlCipher Cipher,
1396 const void *pData, sal_Size nDatLen,
1397 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1399 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1400 if (!pImpl)
1401 return rtl_Cipher_E_Argument;
1403 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1404 return rtl_Cipher_E_Algorithm;
1406 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1407 return rtl_Cipher_E_Direction;
1409 return rtl_cipherARCFOUR_update_Impl(
1410 &(pImpl->m_context),
1411 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1414 void SAL_CALL rtl_cipher_destroyARCFOUR(rtlCipher Cipher) SAL_THROW_EXTERN_C()
1416 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1417 if (!pImpl)
1418 return;
1420 if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmARCFOUR)
1422 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1423 if (pImpl->m_context.m_context != nullptr) {
1424 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1426 #endif
1427 rtl_freeZeroMemory(pImpl, sizeof(CipherARCFOUR_Impl));
1429 else
1430 free(pImpl);
1433 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */