Avoid potential negative array index access to cached text.
[LibreOffice.git] / sal / rtl / cipher.cxx
bloba58c6eef7adc46777147914e5564a43050e6f445
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>
27 #if defined LIBO_CIPHER_OPENSSL_BACKEND
28 #include <openssl/evp.h>
29 #endif
31 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
32 #define RTL_CIPHER_NTOHL(c, l) \
33 ((l) = (static_cast<sal_uInt32>(*((c)++))) << 24, \
34 (l) |= (static_cast<sal_uInt32>(*((c)++))) << 16, \
35 (l) |= (static_cast<sal_uInt32>(*((c)++))) << 8, \
36 (l) |= (static_cast<sal_uInt32>(*((c)++))))
38 #define RTL_CIPHER_HTONL(l, c) \
39 (*((c)++) = static_cast<sal_uInt8>(((l) >> 24) & 0xff), \
40 *((c)++) = static_cast<sal_uInt8>(((l) >> 16) & 0xff), \
41 *((c)++) = static_cast<sal_uInt8>(((l) >> 8) & 0xff), \
42 *((c)++) = static_cast<sal_uInt8>(((l) ) & 0xff))
44 #define RTL_CIPHER_NTOHL64(c, xl, xr, n) \
45 { \
46 (xl) = (xr) = 0; \
47 (c) += (n); \
48 switch ((n)) \
49 { \
50 case 8: (xr) = (static_cast<sal_uInt32>(*(--(c)))); \
51 [[fallthrough]]; \
52 case 7: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 8; \
53 [[fallthrough]]; \
54 case 6: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 16; \
55 [[fallthrough]]; \
56 case 5: (xr) |= (static_cast<sal_uInt32>(*(--(c)))) << 24; \
57 [[fallthrough]]; \
58 case 4: (xl) = (static_cast<sal_uInt32>(*(--(c)))); \
59 [[fallthrough]]; \
60 case 3: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 8; \
61 [[fallthrough]]; \
62 case 2: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 16; \
63 [[fallthrough]]; \
64 case 1: (xl) |= (static_cast<sal_uInt32>(*(--(c)))) << 24; \
65 } \
68 #define RTL_CIPHER_HTONL64(xl, xr, c, n) \
69 { \
70 (c) += (n); \
71 switch ((n)) \
72 { \
73 case 8: *(--(c)) = static_cast<sal_uInt8>(((xr) ) & 0xff); \
74 [[fallthrough]]; \
75 case 7: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 8) & 0xff); \
76 [[fallthrough]]; \
77 case 6: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 16) & 0xff); \
78 [[fallthrough]]; \
79 case 5: *(--(c)) = static_cast<sal_uInt8>(((xr) >> 24) & 0xff); \
80 [[fallthrough]]; \
81 case 4: *(--(c)) = static_cast<sal_uInt8>(((xl) ) & 0xff); \
82 [[fallthrough]]; \
83 case 3: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 8) & 0xff); \
84 [[fallthrough]]; \
85 case 2: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 16) & 0xff); \
86 [[fallthrough]]; \
87 case 1: *(--(c)) = static_cast<sal_uInt8>(((xl) >> 24) & 0xff); \
88 } \
90 #endif
92 typedef rtlCipherError(cipher_init_t) (
93 rtlCipher Cipher,
94 rtlCipherDirection Direction,
95 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
96 const sal_uInt8 *pArgData, sal_Size nArgLen);
98 typedef rtlCipherError(cipher_update_t) (
99 rtlCipher Cipher,
100 const void *pData, sal_Size nDatLen,
101 sal_uInt8 *pBuffer, sal_Size nBufLen);
103 typedef void (cipher_delete_t) (rtlCipher Cipher);
105 namespace {
107 struct Cipher_Impl
109 rtlCipherAlgorithm m_algorithm;
110 rtlCipherDirection m_direction;
111 rtlCipherMode m_mode;
113 cipher_init_t *m_init;
114 cipher_update_t *m_encode;
115 cipher_update_t *m_decode;
116 cipher_delete_t *m_delete;
121 rtlCipher SAL_CALL rtl_cipher_create(
122 rtlCipherAlgorithm Algorithm,
123 rtlCipherMode Mode) SAL_THROW_EXTERN_C()
125 rtlCipher Cipher = nullptr;
126 switch (Algorithm)
128 case rtl_Cipher_AlgorithmBF:
129 Cipher = rtl_cipher_createBF (Mode);
130 break;
132 case rtl_Cipher_AlgorithmARCFOUR:
133 Cipher = rtl_cipher_createARCFOUR (Mode);
134 break;
136 default: /* rtl_Cipher_AlgorithmInvalid */
137 break;
139 return Cipher;
142 rtlCipherError SAL_CALL rtl_cipher_init(
143 rtlCipher Cipher,
144 rtlCipherDirection Direction,
145 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
146 const sal_uInt8 *pArgData, sal_Size nArgLen) SAL_THROW_EXTERN_C()
148 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
149 if (!pImpl)
150 return rtl_Cipher_E_Argument;
152 if (!pImpl->m_init)
153 return rtl_Cipher_E_Unknown;
155 return (pImpl->m_init)(
156 Cipher, Direction, pKeyData, nKeyLen, pArgData, nArgLen);
159 rtlCipherError SAL_CALL rtl_cipher_encode(
160 rtlCipher Cipher,
161 const void *pData, sal_Size nDatLen,
162 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
164 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
165 if (!pImpl)
166 return rtl_Cipher_E_Argument;
168 if (!pImpl->m_encode)
169 return rtl_Cipher_E_Unknown;
171 return (pImpl->m_encode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
174 rtlCipherError SAL_CALL rtl_cipher_decode(
175 rtlCipher Cipher,
176 const void *pData, sal_Size nDatLen,
177 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
179 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
180 if (!pImpl)
181 return rtl_Cipher_E_Argument;
183 if (!pImpl->m_decode)
184 return rtl_Cipher_E_Unknown;
186 return (pImpl->m_decode)(Cipher, pData, nDatLen, pBuffer, nBufLen);
189 void SAL_CALL rtl_cipher_destroy(rtlCipher Cipher) SAL_THROW_EXTERN_C()
191 Cipher_Impl *pImpl = static_cast<Cipher_Impl*>(Cipher);
192 if (pImpl && pImpl->m_delete)
193 pImpl->m_delete(Cipher);
196 namespace {
198 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
199 #define CIPHER_ROUNDS_BF 16
201 struct CipherKeyBF
203 sal_uInt32 m_S[4][256];
204 sal_uInt32 m_P[CIPHER_ROUNDS_BF + 2];
206 #endif
208 struct CipherContextBF
210 #if defined LIBO_CIPHER_OPENSSL_BACKEND
211 EVP_CIPHER_CTX * m_context;
212 #else
213 CipherKeyBF m_key;
214 union
216 sal_uInt32 m_long[2];
217 sal_uInt8 m_byte[8];
218 } m_iv;
219 sal_uInt32 m_offset;
220 #endif
223 struct CipherBF_Impl
225 Cipher_Impl m_cipher;
226 CipherContextBF m_context;
231 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
232 static rtlCipherError BF_init(
233 CipherContextBF *ctx,
234 rtlCipherMode eMode,
235 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
236 const sal_uInt8 *pArgData, sal_Size nArgLen);
237 #endif
239 static rtlCipherError BF_update(
240 CipherContextBF *ctx,
241 rtlCipherMode eMode,
242 rtlCipherDirection eDirection,
243 const sal_uInt8 *pData, sal_Size nDatLen,
244 sal_uInt8 *pBuffer, sal_Size nBufLen);
246 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
247 static void BF_updateECB(
248 CipherContextBF *ctx,
249 rtlCipherDirection direction,
250 const sal_uInt8 *pData,
251 sal_uInt8 *pBuffer,
252 sal_Size nLength);
254 static void BF_updateCBC(
255 CipherContextBF *ctx,
256 rtlCipherDirection direction,
257 const sal_uInt8 *pData,
258 sal_uInt8 *pBuffer,
259 sal_Size nLength);
261 static void BF_updateCFB(
262 CipherContextBF *ctx,
263 rtlCipherDirection direction,
264 const sal_uInt8 *pData,
265 sal_uInt8 *pBuffer);
267 static void BF_encode(CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
269 static void BF_decode(CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr);
271 static sal_uInt32 BF(CipherKeyBF *key, sal_uInt32 x);
273 const CipherKeyBF BF_key =
275 /* S */
277 /* S[0] */
279 /* 0 */
280 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L,
281 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L,
282 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L,
283 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL,
285 /* 1 */
286 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL,
287 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L,
288 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL,
289 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL,
291 /* 2 */
292 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L,
293 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L,
294 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL,
295 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL,
297 /* 3 */
298 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL,
299 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L,
300 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L,
301 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L,
303 /* 4 */
304 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L,
305 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L,
306 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL,
307 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L,
309 /* 5 */
310 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L,
311 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L,
312 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L,
313 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL,
315 /* 6 */
316 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L,
317 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL,
318 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL,
319 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L,
321 /* 7 */
322 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL,
323 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L,
324 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL,
325 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L,
327 /* 8 */
328 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L,
329 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL,
330 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L,
331 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L,
333 /* 9 */
334 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL,
335 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L,
336 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL,
337 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L,
339 /* A */
340 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L,
341 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL,
342 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L,
343 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L,
345 /* B */
346 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L,
347 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L,
348 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L,
349 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL,
351 /* C */
352 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL,
353 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L,
354 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L,
355 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L,
357 /* D */
358 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L,
359 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL,
360 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L,
361 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL,
363 /* E */
364 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL,
365 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L,
366 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L,
367 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L,
369 /* F */
370 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L,
371 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L,
372 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L,
373 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL
376 /* S[1] */
378 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L,
379 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L,
380 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L,
381 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL,
383 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L,
384 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L,
385 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL,
386 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L,
388 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L,
389 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L,
390 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL,
391 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL,
393 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L,
394 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L,
395 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L,
396 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L,
398 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL,
399 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL,
400 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL,
401 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L,
403 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL,
404 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L,
405 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L,
406 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL,
408 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL,
409 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L,
410 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL,
411 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L,
413 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL,
414 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL,
415 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L,
416 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L,
418 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L,
419 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L,
420 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L,
421 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L,
423 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L,
424 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL,
425 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L,
426 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL,
428 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L,
429 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L,
430 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L,
431 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L,
433 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L,
434 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L,
435 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L,
436 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L,
438 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L,
439 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L,
440 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L,
441 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L,
443 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L,
444 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L,
445 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L,
446 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L,
448 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL,
449 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL,
450 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L,
451 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL,
453 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L,
454 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L,
455 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L,
456 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L
459 /* S[2] */
461 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L,
462 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L,
463 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL,
464 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L,
466 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L,
467 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L,
468 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL,
469 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL,
471 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL,
472 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L,
473 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L,
474 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL,
476 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L,
477 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL,
478 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L,
479 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL,
481 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L,
482 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL,
483 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L,
484 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL,
486 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L,
487 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L,
488 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL,
489 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L,
491 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L,
492 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L,
493 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L,
494 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL,
496 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L,
497 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL,
498 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L,
499 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL,
501 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L,
502 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL,
503 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL,
504 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL,
506 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L,
507 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L,
508 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL,
509 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL,
511 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL,
512 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL,
513 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL,
514 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L,
516 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L,
517 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L,
518 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L,
519 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL,
521 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL,
522 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L,
523 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L,
524 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L,
526 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L,
527 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L,
528 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L,
529 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L,
531 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L,
532 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L,
533 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L,
534 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL,
536 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L,
537 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL,
538 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L,
539 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L
542 /* S[3] */
544 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL,
545 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL,
546 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL,
547 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L,
549 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L,
550 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L,
551 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L,
552 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L,
554 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L,
555 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L,
556 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L,
557 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L,
559 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L,
560 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L,
561 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L,
562 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL,
564 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL,
565 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L,
566 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL,
567 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL,
569 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL,
570 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L,
571 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL,
572 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL,
574 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L,
575 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L,
576 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L,
577 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L,
579 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL,
580 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL,
581 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L,
582 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L,
584 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L,
585 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL,
586 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L,
587 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L,
589 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L,
590 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL,
591 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L,
592 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L,
594 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L,
595 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL,
596 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL,
597 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L,
599 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L,
600 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L,
601 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L,
602 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL,
604 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L,
605 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL,
606 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL,
607 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L,
609 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L,
610 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL,
611 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L,
612 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL,
614 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L,
615 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL,
616 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L,
617 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L,
619 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL,
620 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L,
621 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL,
622 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L
626 /* P */
628 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
629 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
630 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL,
631 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L,
632 0x9216D5D9L, 0x8979FB1BL
635 #endif
637 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
638 static rtlCipherError BF_init(
639 CipherContextBF *ctx,
640 rtlCipherMode eMode,
641 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
642 const sal_uInt8 *pArgData, sal_Size nArgLen)
644 CipherKeyBF *key;
645 sal_uInt32 D, DL, DR;
646 sal_uInt16 i, j, k;
648 key = &(ctx->m_key);
650 memcpy(key, &BF_key, sizeof (CipherKeyBF));
651 memset(&(ctx->m_iv), 0, sizeof(ctx->m_iv));
652 ctx->m_offset = 0;
654 for (i = 0, k = 0; i < CIPHER_ROUNDS_BF + 2; ++i)
656 D = 0;
657 for (j = 0; j < 4; ++j)
659 D = ((D << 8) | pKeyData[k]);
660 k++;
661 if (k >= nKeyLen)
662 k = 0;
664 key->m_P[i] ^= D;
667 rtl_secureZeroMemory(&DL, sizeof(DL));
668 rtl_secureZeroMemory(&DR, sizeof(DR));
670 for (i = 0; i < CIPHER_ROUNDS_BF + 2; i += 2)
672 BF_encode(key, &DL, &DR);
673 key->m_P[i ] = DL;
674 key->m_P[i + 1] = DR;
677 for (i = 0; i < 4; ++i)
679 for (k = 0; k < 256; k += 2)
681 BF_encode(key, &DL, &DR);
682 key->m_S[i][k ] = DL;
683 key->m_S[i][k + 1] = DR;
687 if (pArgData && nArgLen)
689 nArgLen = std::min<sal_Size>(nArgLen, 8);
690 if (eMode == rtl_Cipher_ModeStream)
692 memcpy(ctx->m_iv.m_byte, pArgData, nArgLen);
694 else
696 RTL_CIPHER_NTOHL64 (pArgData, DL, DR, nArgLen);
697 ctx->m_iv.m_long[0] = DL;
698 ctx->m_iv.m_long[1] = DR;
702 return rtl_Cipher_E_None;
704 #endif
706 static rtlCipherError BF_update(
707 CipherContextBF *ctx,
708 rtlCipherMode eMode,
709 rtlCipherDirection eDirection,
710 const sal_uInt8 *pData, sal_Size nDatLen,
711 sal_uInt8 *pBuffer, sal_Size nBufLen)
713 /* Check arguments. */
714 if (!pData || !pBuffer)
715 return rtl_Cipher_E_Argument;
717 if ((nDatLen <= 0) || (nDatLen > nBufLen))
718 return rtl_Cipher_E_BufferSize;
720 /* Update. */
721 #if defined LIBO_CIPHER_OPENSSL_BACKEND
722 assert(eMode == rtl_Cipher_ModeStream);
723 (void) eMode;
724 (void) eDirection;
725 while (nDatLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
726 int outl;
727 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, std::numeric_limits<int>::max())
728 == 0)
730 return rtl_Cipher_E_Unknown;
732 assert(outl == std::numeric_limits<int>::max());
733 pData += std::numeric_limits<int>::max();
734 nDatLen -= std::numeric_limits<int>::max();
735 pBuffer += std::numeric_limits<int>::max();
737 int outl;
738 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, static_cast<int>(nDatLen)) == 0)
740 return rtl_Cipher_E_Unknown;
742 assert(outl == static_cast<int>(nDatLen));
743 // A final call to EVP_CipherFinal_ex is intentionally missing; it wouldn't fit the rtl/cipher.h
744 // interface, and is hopefully not needed, as each individual Blowfish CFB update step doesn't
745 // hold back any data that would need to be finally flushed.
746 #else
747 if (eMode == rtl_Cipher_ModeECB)
749 /* Block mode. */
750 while (nDatLen > 8)
752 BF_updateECB(ctx, eDirection, pData, pBuffer, 8);
753 nDatLen -= 8;
754 pData += 8;
755 pBuffer += 8;
757 BF_updateECB(ctx, eDirection, pData, pBuffer, nDatLen);
759 else if (eMode == rtl_Cipher_ModeCBC)
761 /* Block mode. */
762 while (nDatLen > 8)
764 BF_updateCBC (ctx, eDirection, pData, pBuffer, 8);
765 nDatLen -= 8;
766 pData += 8;
767 pBuffer += 8;
769 BF_updateCBC (ctx, eDirection, pData, pBuffer, nDatLen);
771 else
773 /* Stream mode. */
774 while (nDatLen > 0)
776 BF_updateCFB (ctx, eDirection, pData, pBuffer);
777 nDatLen -= 1;
778 pData += 1;
779 pBuffer += 1;
782 #endif
783 return rtl_Cipher_E_None;
786 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
787 static void BF_updateECB(
788 CipherContextBF *ctx,
789 rtlCipherDirection direction,
790 const sal_uInt8 *pData,
791 sal_uInt8 *pBuffer,
792 sal_Size nLength)
794 CipherKeyBF *key;
795 sal_uInt32 DL, DR;
797 key = &(ctx->m_key);
798 if (direction == rtl_Cipher_DirectionEncode)
800 RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
802 BF_encode(key, &DL, &DR);
804 RTL_CIPHER_HTONL(DL, pBuffer);
805 RTL_CIPHER_HTONL(DR, pBuffer);
807 else
809 RTL_CIPHER_NTOHL(pData, DL);
810 RTL_CIPHER_NTOHL(pData, DR);
812 BF_decode(key, &DL, &DR);
814 RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
816 rtl_secureZeroMemory(&DL, sizeof(DL));
817 rtl_secureZeroMemory(&DR, sizeof(DR));
820 static void BF_updateCBC(
821 CipherContextBF *ctx,
822 rtlCipherDirection direction,
823 const sal_uInt8 *pData,
824 sal_uInt8 *pBuffer,
825 sal_Size nLength)
827 CipherKeyBF *key;
828 sal_uInt32 DL, DR;
830 key = &(ctx->m_key);
831 if (direction == rtl_Cipher_DirectionEncode)
833 RTL_CIPHER_NTOHL64(pData, DL, DR, nLength);
835 DL ^= ctx->m_iv.m_long[0];
836 DR ^= ctx->m_iv.m_long[1];
838 BF_encode(key, &DL, &DR);
840 ctx->m_iv.m_long[0] = DL;
841 ctx->m_iv.m_long[1] = DR;
843 RTL_CIPHER_HTONL(DL, pBuffer);
844 RTL_CIPHER_HTONL(DR, pBuffer);
846 else
848 sal_uInt32 IVL, IVR;
850 RTL_CIPHER_NTOHL(pData, DL);
851 RTL_CIPHER_NTOHL(pData, DR);
853 IVL = DL;
854 IVR = DR;
856 BF_decode(key, &DL, &DR);
858 DL ^= ctx->m_iv.m_long[0];
859 DR ^= ctx->m_iv.m_long[1];
861 ctx->m_iv.m_long[0] = IVL;
862 ctx->m_iv.m_long[1] = IVR;
864 RTL_CIPHER_HTONL64(DL, DR, pBuffer, nLength);
866 rtl_secureZeroMemory(&DL, sizeof(DL));
867 rtl_secureZeroMemory(&DR, sizeof(DR));
870 static void BF_updateCFB(
871 CipherContextBF *ctx,
872 rtlCipherDirection direction,
873 const sal_uInt8 *pData,
874 sal_uInt8 *pBuffer)
876 sal_uInt8 *iv;
877 sal_uInt32 k;
879 iv = ctx->m_iv.m_byte;
880 k = ctx->m_offset;
882 if (k == 0)
884 sal_uInt32 IVL, IVR;
886 RTL_CIPHER_NTOHL64(iv, IVL, IVR, 8);
887 BF_encode(&(ctx->m_key), &IVL, &IVR);
888 RTL_CIPHER_HTONL64(IVL, IVR, iv, 8);
890 rtl_secureZeroMemory(&IVL, sizeof(IVL));
891 rtl_secureZeroMemory(&IVR, sizeof(IVR));
894 if (direction == rtl_Cipher_DirectionEncode)
896 iv[k] ^= *pData;
897 *pBuffer = iv[k];
899 else
901 sal_uInt8 c = iv[k];
902 iv[k] = *pData;
903 *pBuffer = *pData ^ c;
906 ctx->m_offset = ((k + 1) & 0x07);
907 iv = nullptr;
910 static void BF_encode(
911 CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
913 sal_uInt32 t, XL, XR;
914 sal_uInt16 i;
916 XL = *xl;
917 XR = *xr;
919 for (i = 0; i < CIPHER_ROUNDS_BF; ++i)
921 XL ^= key->m_P[i];
922 XR ^= BF (key, XL);
924 t = XL;
925 XL = XR;
926 XR = t;
929 t = XL;
930 XL = XR;
931 XR = t;
933 XR ^= key->m_P[CIPHER_ROUNDS_BF ];
934 XL ^= key->m_P[CIPHER_ROUNDS_BF + 1];
936 *xl = XL;
937 *xr = XR;
941 static void BF_decode(
942 CipherKeyBF *key, sal_uInt32 *xl, sal_uInt32 *xr)
944 sal_uInt32 t, XL, XR;
945 sal_uInt16 i;
947 XL = *xl;
948 XR = *xr;
950 for (i = CIPHER_ROUNDS_BF + 1; i > 1; --i)
952 XL ^= key->m_P[i];
953 XR ^= BF (key, XL);
955 t = XL;
956 XL = XR;
957 XR = t;
960 t = XL;
961 XL = XR;
962 XR = t;
964 XR ^= key->m_P[1];
965 XL ^= key->m_P[0];
967 *xl = XL;
968 *xr = XR;
972 static sal_uInt32 BF(CipherKeyBF *key, sal_uInt32 x)
974 sal_uInt16 a, b, c, d;
975 sal_uInt32 y;
977 d = static_cast<sal_uInt16>(x & 0x00ff);
978 x >>= 8;
979 c = static_cast<sal_uInt16>(x & 0x00ff);
980 x >>= 8;
981 b = static_cast<sal_uInt16>(x & 0x00ff);
982 x >>= 8;
983 a = static_cast<sal_uInt16>(x & 0x00ff);
985 y = key->m_S[0][a];
986 y += key->m_S[1][b];
987 y ^= key->m_S[2][c];
988 y += key->m_S[3][d];
990 return y;
992 #endif
995 rtl_cipherBF (Blowfish) implementation.
997 Reference: Bruce Schneier: Applied Cryptography, 2nd edition, ch. 14.3
999 rtlCipher SAL_CALL rtl_cipher_createBF(rtlCipherMode Mode) SAL_THROW_EXTERN_C()
1001 CipherBF_Impl *pImpl = nullptr;
1003 if (Mode == rtl_Cipher_ModeInvalid)
1004 return nullptr;
1005 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1006 if (Mode != rtl_Cipher_ModeStream) {
1007 // Cannot easily support ModeECB and ModeCBC, and they aren't used in the LO code at least:
1008 return nullptr;
1010 #endif
1012 pImpl = static_cast<CipherBF_Impl*>(rtl_allocateZeroMemory(sizeof (CipherBF_Impl)));
1013 if (pImpl)
1015 pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmBF;
1016 pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1017 pImpl->m_cipher.m_mode = Mode;
1019 pImpl->m_cipher.m_init = rtl_cipher_initBF;
1020 pImpl->m_cipher.m_encode = rtl_cipher_encodeBF;
1021 pImpl->m_cipher.m_decode = rtl_cipher_decodeBF;
1022 pImpl->m_cipher.m_delete = rtl_cipher_destroyBF;
1024 return static_cast<rtlCipher>(pImpl);
1027 rtlCipherError SAL_CALL rtl_cipher_initBF(
1028 rtlCipher Cipher,
1029 rtlCipherDirection Direction,
1030 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1031 const sal_uInt8 *pArgData, sal_Size nArgLen) SAL_THROW_EXTERN_C()
1033 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1035 if (!pImpl || !pKeyData)
1036 return rtl_Cipher_E_Argument;
1038 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1039 return rtl_Cipher_E_Algorithm;
1041 if (Direction != rtl_Cipher_DirectionInvalid)
1042 pImpl->m_cipher.m_direction = Direction;
1043 else
1044 return rtl_Cipher_E_Direction;
1046 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1047 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionBoth) {
1048 // Cannot easily support DirectionBoth, and it isn't used in the LO code at least:
1049 return rtl_Cipher_E_Direction;
1051 if (nKeyLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1052 return rtl_Cipher_E_BufferSize;
1054 if (pImpl->m_context.m_context != nullptr) {
1055 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1057 pImpl->m_context.m_context = EVP_CIPHER_CTX_new();
1058 if (pImpl->m_context.m_context == nullptr) {
1059 return rtl_Cipher_E_Memory;
1061 unsigned char iv[8];
1062 auto const n = std::min(nArgLen, sal_Size(8));
1063 std::memcpy(iv, pArgData, n);
1064 std::memset(iv + n, 0, 8 - n);
1065 if (EVP_CipherInit_ex(
1066 pImpl->m_context.m_context, EVP_bf_cfb(), nullptr, nullptr, iv,
1067 pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode ? 0 : 1)
1068 == 0)
1070 return rtl_Cipher_E_Unknown;
1072 if (EVP_CIPHER_CTX_set_key_length(pImpl->m_context.m_context, static_cast<int>(nKeyLen)) == 0) {
1073 return rtl_Cipher_E_Unknown;
1075 if (EVP_CipherInit_ex(pImpl->m_context.m_context, nullptr, nullptr, pKeyData, nullptr, -1) == 0)
1077 return rtl_Cipher_E_Unknown;
1079 return rtl_Cipher_E_None;
1080 #else
1081 return BF_init(
1082 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1083 pKeyData, nKeyLen, pArgData, nArgLen);
1084 #endif
1087 rtlCipherError SAL_CALL rtl_cipher_encodeBF(
1088 rtlCipher Cipher,
1089 const void *pData, sal_Size nDatLen,
1090 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1092 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1093 if (!pImpl)
1094 return rtl_Cipher_E_Argument;
1096 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1097 return rtl_Cipher_E_Algorithm;
1099 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1100 return rtl_Cipher_E_Direction;
1102 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionDecode)
1103 return rtl_Cipher_E_Direction;
1105 return BF_update(
1106 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1107 rtl_Cipher_DirectionEncode,
1108 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1111 rtlCipherError SAL_CALL rtl_cipher_decodeBF(
1112 rtlCipher Cipher,
1113 const void *pData, sal_Size nDatLen,
1114 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1116 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1117 if (!pImpl)
1118 return rtl_Cipher_E_Argument;
1120 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmBF)
1121 return rtl_Cipher_E_Algorithm;
1123 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1124 return rtl_Cipher_E_Direction;
1126 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionEncode)
1127 return rtl_Cipher_E_Direction;
1129 return BF_update(
1130 &(pImpl->m_context), pImpl->m_cipher.m_mode,
1131 rtl_Cipher_DirectionDecode,
1132 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1135 void SAL_CALL rtl_cipher_destroyBF(rtlCipher Cipher) SAL_THROW_EXTERN_C()
1137 CipherBF_Impl *pImpl = static_cast<CipherBF_Impl*>(Cipher);
1138 if (!pImpl)
1139 return;
1141 if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmBF)
1143 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1144 if (pImpl->m_context.m_context != nullptr) {
1145 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1147 #endif
1148 rtl_freeZeroMemory(pImpl, sizeof(CipherBF_Impl));
1150 else
1151 free(pImpl);
1154 #if !defined LIBO_CIPHER_OPENSSL_BACKEND
1155 #define CIPHER_CBLOCK_ARCFOUR 256
1156 #endif
1158 namespace {
1160 struct ContextARCFOUR_Impl
1162 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1163 EVP_CIPHER_CTX * m_context;
1164 #else
1165 unsigned int m_S[CIPHER_CBLOCK_ARCFOUR];
1166 unsigned int m_X, m_Y;
1167 #endif
1170 struct CipherARCFOUR_Impl
1172 Cipher_Impl m_cipher;
1173 ContextARCFOUR_Impl m_context;
1178 static rtlCipherError rtl_cipherARCFOUR_update_Impl(
1179 ContextARCFOUR_Impl *ctx,
1180 const sal_uInt8 *pData, sal_Size nDatLen,
1181 sal_uInt8 *pBuffer, sal_Size nBufLen);
1183 static rtlCipherError rtl_cipherARCFOUR_init_Impl(
1184 ContextARCFOUR_Impl *ctx,
1185 const sal_uInt8 *pKeyData, sal_Size nKeyLen)
1187 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1188 if (nKeyLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1189 return rtl_Cipher_E_BufferSize;
1191 if (ctx->m_context != nullptr) {
1192 EVP_CIPHER_CTX_free(ctx->m_context);
1194 ctx->m_context = EVP_CIPHER_CTX_new();
1195 if (ctx->m_context == nullptr) {
1196 return rtl_Cipher_E_Memory;
1198 if (EVP_CipherInit_ex(ctx->m_context, EVP_rc4(), nullptr, nullptr, nullptr, 0) == 0) {
1199 // RC4 en- and decryption is identical, so we can use 0=decrypt regardless of direction,
1200 // and thus also support rtl_Cipher_DirectionBoth
1201 return rtl_Cipher_E_Unknown;
1203 if (EVP_CIPHER_CTX_set_key_length(ctx->m_context, static_cast<int>(nKeyLen)) == 0) {
1204 return rtl_Cipher_E_Unknown;
1206 if (EVP_CipherInit_ex(ctx->m_context, nullptr, nullptr, pKeyData, nullptr, -1) == 0) {
1207 return rtl_Cipher_E_Unknown;
1209 #else
1210 unsigned int K[CIPHER_CBLOCK_ARCFOUR];
1211 unsigned int *L, *S;
1212 unsigned int x, y;
1213 sal_Size n, k;
1215 S = &(ctx->m_S[0]);
1217 /* Initialize S linearly. */
1218 for (x = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1219 S[x] = x;
1221 /* Initialize K with key, repeat key as necessary. */
1222 for (L = K, n = CIPHER_CBLOCK_ARCFOUR; n > nKeyLen; n -= nKeyLen)
1224 for (k = 0; k < nKeyLen; k++)
1226 L[k] = pKeyData[k];
1229 L += nKeyLen;
1232 for (k = 0; k < n; k++)
1234 L[k] = pKeyData[k];
1237 /* Initialize S with K. */
1238 for (x = 0, y = 0; x < CIPHER_CBLOCK_ARCFOUR; x++)
1240 y = (y + S[x] + K[x]) % CIPHER_CBLOCK_ARCFOUR;
1241 /* swap S[x] and S[y] */
1242 unsigned int t = S[x];
1243 S[x] = S[y];
1244 S[y] = t;
1247 /* Initialize counters X and Y. */
1248 ctx->m_X = 0;
1249 ctx->m_Y = 0;
1250 #endif
1252 return rtl_Cipher_E_None;
1255 static rtlCipherError rtl_cipherARCFOUR_update_Impl(
1256 ContextARCFOUR_Impl *ctx,
1257 const sal_uInt8 *pData, sal_Size nDatLen,
1258 sal_uInt8 *pBuffer, sal_Size nBufLen)
1260 /* Check arguments. */
1261 if (!pData || !pBuffer)
1262 return rtl_Cipher_E_Argument;
1264 if ((0 >= nDatLen) || (nDatLen > nBufLen))
1265 return rtl_Cipher_E_BufferSize;
1267 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1268 while (nDatLen > o3tl::make_unsigned(std::numeric_limits<int>::max())) {
1269 int outl;
1270 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, std::numeric_limits<int>::max())
1271 == 0)
1273 return rtl_Cipher_E_Unknown;
1275 assert(outl == std::numeric_limits<int>::max());
1276 pData += std::numeric_limits<int>::max();
1277 nDatLen -= std::numeric_limits<int>::max();
1278 pBuffer += std::numeric_limits<int>::max();
1280 int outl;
1281 if (EVP_CipherUpdate(ctx->m_context, pBuffer, &outl, pData, static_cast<int>(nDatLen)) == 0) {
1282 return rtl_Cipher_E_Unknown;
1284 assert(outl == static_cast<int>(nDatLen));
1285 // A final call to EVP_CipherFinal_ex is intentionally missing; it wouldn't fit the rtl/cipher.h
1286 // interface, and is hopefully not needed, as each individual RC4 update step doesn't hold back
1287 // any data that would need to be finally flushed.
1288 #else
1289 unsigned int *S;
1290 sal_Size k;
1292 /* Update. */
1293 S = &(ctx->m_S[0]);
1294 for (k = 0; k < nDatLen; k++)
1296 /* Update counters X and Y. */
1297 unsigned int x = ctx->m_X;
1298 unsigned int y = ctx->m_Y;
1299 x = (x + 1 ) % CIPHER_CBLOCK_ARCFOUR;
1300 y = (y + S[x]) % CIPHER_CBLOCK_ARCFOUR;
1301 ctx->m_X = x;
1302 ctx->m_Y = y;
1304 /* Swap S[x] and S[y]. */
1305 unsigned int t = S[x];
1306 S[x] = S[y];
1307 S[y] = t;
1309 /* Evaluate next key byte S[t]. */
1310 t = (S[x] + S[y]) % CIPHER_CBLOCK_ARCFOUR;
1311 pBuffer[k] = pData[k] ^ static_cast<sal_uInt8>(S[t] & 0xff);
1313 #endif
1315 return rtl_Cipher_E_None;
1319 rtl_cipher_ARCFOUR (RC4) implementation.
1321 Reference: Bruce Schneier: Applied Cryptography, 2nd edition, ch. 17.1
1323 rtlCipher SAL_CALL rtl_cipher_createARCFOUR(rtlCipherMode Mode)
1324 SAL_THROW_EXTERN_C()
1326 CipherARCFOUR_Impl *pImpl = nullptr;
1328 if (Mode != rtl_Cipher_ModeStream)
1329 return nullptr;
1331 pImpl = static_cast<CipherARCFOUR_Impl*>(rtl_allocateZeroMemory(sizeof(CipherARCFOUR_Impl)));
1332 if (pImpl)
1334 pImpl->m_cipher.m_algorithm = rtl_Cipher_AlgorithmARCFOUR;
1335 pImpl->m_cipher.m_direction = rtl_Cipher_DirectionInvalid;
1336 pImpl->m_cipher.m_mode = rtl_Cipher_ModeStream;
1338 pImpl->m_cipher.m_init = rtl_cipher_initARCFOUR;
1339 pImpl->m_cipher.m_encode = rtl_cipher_encodeARCFOUR;
1340 pImpl->m_cipher.m_decode = rtl_cipher_decodeARCFOUR;
1341 pImpl->m_cipher.m_delete = rtl_cipher_destroyARCFOUR;
1344 return static_cast<rtlCipher>(pImpl);
1347 rtlCipherError SAL_CALL rtl_cipher_initARCFOUR(
1348 rtlCipher Cipher,
1349 rtlCipherDirection Direction,
1350 const sal_uInt8 *pKeyData, sal_Size nKeyLen,
1351 SAL_UNUSED_PARAMETER const sal_uInt8 *, SAL_UNUSED_PARAMETER sal_Size)
1352 SAL_THROW_EXTERN_C()
1354 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1356 if (!pImpl || !pKeyData)
1357 return rtl_Cipher_E_Argument;
1359 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1360 return rtl_Cipher_E_Algorithm;
1362 if (Direction != rtl_Cipher_DirectionInvalid)
1363 pImpl->m_cipher.m_direction = Direction;
1364 else
1365 return rtl_Cipher_E_Direction;
1367 return rtl_cipherARCFOUR_init_Impl(&(pImpl->m_context), pKeyData, nKeyLen);
1370 rtlCipherError SAL_CALL rtl_cipher_encodeARCFOUR(
1371 rtlCipher Cipher,
1372 const void *pData, sal_Size nDatLen,
1373 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1375 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1376 if (!pImpl)
1377 return rtl_Cipher_E_Argument;
1379 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1380 return rtl_Cipher_E_Algorithm;
1382 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1383 return rtl_Cipher_E_Direction;
1385 return rtl_cipherARCFOUR_update_Impl(
1386 &(pImpl->m_context),
1387 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1390 rtlCipherError SAL_CALL rtl_cipher_decodeARCFOUR(
1391 rtlCipher Cipher,
1392 const void *pData, sal_Size nDatLen,
1393 sal_uInt8 *pBuffer, sal_Size nBufLen) SAL_THROW_EXTERN_C()
1395 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1396 if (!pImpl)
1397 return rtl_Cipher_E_Argument;
1399 if (pImpl->m_cipher.m_algorithm != rtl_Cipher_AlgorithmARCFOUR)
1400 return rtl_Cipher_E_Algorithm;
1402 if (pImpl->m_cipher.m_direction == rtl_Cipher_DirectionInvalid)
1403 return rtl_Cipher_E_Direction;
1405 return rtl_cipherARCFOUR_update_Impl(
1406 &(pImpl->m_context),
1407 static_cast<const sal_uInt8*>(pData), nDatLen, pBuffer, nBufLen);
1410 void SAL_CALL rtl_cipher_destroyARCFOUR(rtlCipher Cipher) SAL_THROW_EXTERN_C()
1412 CipherARCFOUR_Impl *pImpl = static_cast<CipherARCFOUR_Impl*>(Cipher);
1413 if (!pImpl)
1414 return;
1416 if (pImpl->m_cipher.m_algorithm == rtl_Cipher_AlgorithmARCFOUR)
1418 #if defined LIBO_CIPHER_OPENSSL_BACKEND
1419 if (pImpl->m_context.m_context != nullptr) {
1420 EVP_CIPHER_CTX_free(pImpl->m_context.m_context);
1422 #endif
1423 rtl_freeZeroMemory(pImpl, sizeof(CipherARCFOUR_Impl));
1425 else
1426 free(pImpl);
1429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */