Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / oox / source / crypto / CryptTools.cxx
blobb23d3ebbf57b00b336f67d4490dca469221b8af0
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 */
11 #include "oox/crypto/CryptTools.hxx"
12 #include <filter/msfilter/mscodec.hxx>
13 #include <com/sun/star/uno/RuntimeException.hpp>
15 namespace oox {
16 namespace core {
18 Crypto::Crypto()
19 #if USE_TLS_NSS
20 : mContext(nullptr)
21 , mSecParam(nullptr)
22 , mSymKey(nullptr)
23 #endif
25 #if USE_TLS_NSS
26 // Initialize NSS, database functions are not needed
27 NSS_NoDB_Init(nullptr);
28 #endif // USE_TLS_NSS
31 Crypto::~Crypto()
33 #if USE_TLS_OPENSSL
34 EVP_CIPHER_CTX_cleanup( &mContext );
35 #endif
36 #if USE_TLS_NSS
37 PK11_DestroyContext( mContext, PR_TRUE );
38 PK11_FreeSymKey( mSymKey );
39 SECITEM_FreeItem( mSecParam, PR_TRUE );
40 #endif
43 #if USE_TLS_OPENSSL
44 const EVP_CIPHER* Crypto::getCipher(CryptoType type)
46 switch(type)
48 case AES_128_ECB:
49 return EVP_aes_128_ecb();
50 case AES_128_CBC:
51 return EVP_aes_128_cbc();
52 case AES_256_CBC:
53 return EVP_aes_256_cbc();
54 default:
55 break;
57 return NULL;
59 #endif
61 #if USE_TLS_NSS
62 void Crypto::setupContext(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type, CK_ATTRIBUTE_TYPE operation)
64 CK_MECHANISM_TYPE mechanism = static_cast<CK_ULONG>(-1);
66 SECItem ivItem;
67 ivItem.type = siBuffer;
68 if(iv.empty())
69 ivItem.data = nullptr;
70 else
71 ivItem.data = iv.data();
72 ivItem.len = iv.size();
74 SECItem* pIvItem = nullptr;
76 switch(type)
78 case AES_128_ECB:
79 mechanism = CKM_AES_ECB;
80 break;
81 case AES_128_CBC:
82 mechanism = CKM_AES_CBC;
83 pIvItem = &ivItem;
84 break;
85 case AES_256_CBC:
86 mechanism = CKM_AES_CBC;
87 pIvItem = &ivItem;
88 break;
89 default:
90 break;
93 PK11SlotInfo* pSlot(PK11_GetBestSlot(mechanism, nullptr));
95 if (!pSlot)
96 throw css::uno::RuntimeException("NSS Slot failure", css::uno::Reference<css::uno::XInterface>());
98 SECItem keyItem;
99 keyItem.type = siBuffer;
100 keyItem.data = key.data();
101 keyItem.len = key.size();
103 mSymKey = PK11_ImportSymKey(pSlot, mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr);
104 mSecParam = PK11_ParamFromIV(mechanism, pIvItem);
105 mContext = PK11_CreateContextBySymKey(mechanism, operation, mSymKey, mSecParam);
107 #endif // USE_TLS_NSS
109 // DECRYPT
111 Decrypt::Decrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type)
112 : Crypto()
114 #if USE_TLS_OPENSSL
115 EVP_CIPHER_CTX_init(&mContext);
117 const EVP_CIPHER* cipher = getCipher(type);
119 if (iv.empty())
120 EVP_DecryptInit_ex(&mContext, cipher, nullptr, key.data(), 0);
121 else
122 EVP_DecryptInit_ex(&mContext, cipher, nullptr, key.data(), iv.data());
123 EVP_CIPHER_CTX_set_padding(&mContext, 0);
124 #endif
126 #if USE_TLS_NSS
127 setupContext(key, iv, type, CKA_DECRYPT);
128 #endif // USE_TLS_NSS
131 sal_uInt32 Decrypt::update(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, sal_uInt32 inputLength)
133 int outputLength = 0;
135 sal_uInt32 actualInputLength = inputLength == 0 || inputLength > input.size() ? input.size() : inputLength;
137 #if USE_TLS_OPENSSL
138 (void)EVP_DecryptUpdate(&mContext, output.data(), &outputLength, input.data(), actualInputLength);
139 #endif // USE_TLS_OPENSSL
141 #if USE_TLS_NSS
142 (void)PK11_CipherOp( mContext, output.data(), &outputLength, actualInputLength, input.data(), actualInputLength );
143 #endif // USE_TLS_NSS
145 return static_cast<sal_uInt32>(outputLength);
148 sal_uInt32 Decrypt::aes128ecb(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, std::vector<sal_uInt8>& key)
150 sal_uInt32 outputLength = 0;
151 std::vector<sal_uInt8> iv;
152 Decrypt crypto(key, iv, Crypto::AES_128_ECB);
153 outputLength = crypto.update(output, input);
154 return outputLength;
157 // ENCRYPT
159 Encrypt::Encrypt(std::vector<sal_uInt8>& key, std::vector<sal_uInt8>& iv, CryptoType type)
160 : Crypto()
162 #if USE_TLS_OPENSSL
163 EVP_CIPHER_CTX_init(&mContext);
165 const EVP_CIPHER* cipher = getCipher(type);
167 if (iv.empty())
168 EVP_EncryptInit_ex(&mContext, cipher, nullptr, key.data(), 0);
169 else
170 EVP_EncryptInit_ex(&mContext, cipher, nullptr, key.data(), iv.data());
171 EVP_CIPHER_CTX_set_padding(&mContext, 0);
172 #endif
174 #if USE_TLS_NSS
175 setupContext(key, iv, type, CKA_ENCRYPT);
176 #endif // USE_TLS_NSS
179 sal_uInt32 Encrypt::update(std::vector<sal_uInt8>& output, std::vector<sal_uInt8>& input, sal_uInt32 inputLength)
181 int outputLength = 0;
183 sal_uInt32 actualInputLength = inputLength == 0 || inputLength > input.size() ? input.size() : inputLength;
185 #if USE_TLS_OPENSSL
186 (void)EVP_EncryptUpdate(&mContext, output.data(), &outputLength, input.data(), actualInputLength);
187 #endif // USE_TLS_OPENSSL
189 #if USE_TLS_NSS
190 (void)PK11_CipherOp(mContext, output.data(), &outputLength, actualInputLength, input.data(), actualInputLength);
191 #endif // USE_TLS_NSS
193 return static_cast<sal_uInt32>(outputLength);
196 } // namespace core
197 } // namespace oox
199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */