1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
11 #include <oox/crypto/CryptTools.hxx>
12 #include <filter/msfilter/mscodec.hxx>
13 #include <com/sun/star/uno/RuntimeException.hpp>
26 // Initialize NSS, database functions are not needed
27 NSS_NoDB_Init(nullptr);
34 EVP_CIPHER_CTX_cleanup( &mContext
);
38 PK11_DestroyContext(mContext
, PR_TRUE
);
40 PK11_FreeSymKey(mSymKey
);
42 SECITEM_FreeItem(mSecParam
, PR_TRUE
);
47 const EVP_CIPHER
* Crypto::getCipher(CryptoType type
)
52 return EVP_aes_128_ecb();
54 return EVP_aes_128_cbc();
56 return EVP_aes_256_cbc();
65 void Crypto::setupContext(std::vector
<sal_uInt8
>& key
, std::vector
<sal_uInt8
>& iv
, CryptoType type
, CK_ATTRIBUTE_TYPE operation
)
67 CK_MECHANISM_TYPE mechanism
= static_cast<CK_ULONG
>(-1);
70 ivItem
.type
= siBuffer
;
72 ivItem
.data
= nullptr;
74 ivItem
.data
= iv
.data();
75 ivItem
.len
= iv
.size();
77 SECItem
* pIvItem
= nullptr;
82 mechanism
= CKM_AES_ECB
;
85 mechanism
= CKM_AES_CBC
;
89 mechanism
= CKM_AES_CBC
;
96 PK11SlotInfo
* pSlot(PK11_GetBestSlot(mechanism
, nullptr));
99 throw css::uno::RuntimeException("NSS Slot failure", css::uno::Reference
<css::uno::XInterface
>());
102 keyItem
.type
= siBuffer
;
103 keyItem
.data
= key
.data();
104 keyItem
.len
= key
.size();
106 mSymKey
= PK11_ImportSymKey(pSlot
, mechanism
, PK11_OriginUnwrap
, CKA_ENCRYPT
, &keyItem
, nullptr);
108 throw css::uno::RuntimeException("NSS SymKey failure", css::uno::Reference
<css::uno::XInterface
>());
110 mSecParam
= PK11_ParamFromIV(mechanism
, pIvItem
);
111 mContext
= PK11_CreateContextBySymKey(mechanism
, operation
, mSymKey
, mSecParam
);
113 #endif // USE_TLS_NSS
117 Decrypt::Decrypt(std::vector
<sal_uInt8
>& key
, std::vector
<sal_uInt8
>& iv
, CryptoType type
)
120 #if USE_TLS_OPENSSL + USE_TLS_NSS == 0
127 EVP_CIPHER_CTX_init(&mContext
);
129 const EVP_CIPHER
* cipher
= getCipher(type
);
131 const size_t nMinKeySize
= EVP_CIPHER_key_length(cipher
);
132 if (key
.size() < nMinKeySize
)
133 key
.resize(nMinKeySize
, 0);
136 EVP_DecryptInit_ex(&mContext
, cipher
, nullptr, key
.data(), 0);
139 const size_t nMinIVSize
= EVP_CIPHER_iv_length(cipher
);
140 if (iv
.size() < nMinIVSize
)
141 iv
.resize(nMinIVSize
, 0);
143 EVP_DecryptInit_ex(&mContext
, cipher
, nullptr, key
.data(), iv
.data());
145 EVP_CIPHER_CTX_set_padding(&mContext
, 0);
149 setupContext(key
, iv
, type
, CKA_DECRYPT
);
150 #endif // USE_TLS_NSS
153 sal_uInt32
Decrypt::update(std::vector
<sal_uInt8
>& output
, std::vector
<sal_uInt8
>& input
, sal_uInt32 inputLength
)
155 int outputLength
= 0;
157 #if USE_TLS_OPENSSL + USE_TLS_NSS > 0
158 sal_uInt32 actualInputLength
= inputLength
== 0 || inputLength
> input
.size() ? input
.size() : inputLength
;
166 (void)EVP_DecryptUpdate(&mContext
, output
.data(), &outputLength
, input
.data(), actualInputLength
);
167 #endif // USE_TLS_OPENSSL
172 (void)PK11_CipherOp( mContext
, output
.data(), &outputLength
, actualInputLength
, input
.data(), actualInputLength
);
173 #endif // USE_TLS_NSS
175 return static_cast<sal_uInt32
>(outputLength
);
178 sal_uInt32
Decrypt::aes128ecb(std::vector
<sal_uInt8
>& output
, std::vector
<sal_uInt8
>& input
, std::vector
<sal_uInt8
>& key
)
180 sal_uInt32 outputLength
= 0;
181 std::vector
<sal_uInt8
> iv
;
182 Decrypt
crypto(key
, iv
, Crypto::AES_128_ECB
);
183 outputLength
= crypto
.update(output
, input
);
189 Encrypt::Encrypt(std::vector
<sal_uInt8
>& key
, std::vector
<sal_uInt8
>& iv
, CryptoType type
)
192 #if USE_TLS_OPENSSL + USE_TLS_NSS == 0
199 EVP_CIPHER_CTX_init(&mContext
);
201 const EVP_CIPHER
* cipher
= getCipher(type
);
204 EVP_EncryptInit_ex(&mContext
, cipher
, nullptr, key
.data(), 0);
206 EVP_EncryptInit_ex(&mContext
, cipher
, nullptr, key
.data(), iv
.data());
207 EVP_CIPHER_CTX_set_padding(&mContext
, 0);
211 setupContext(key
, iv
, type
, CKA_ENCRYPT
);
212 #endif // USE_TLS_NSS
215 sal_uInt32
Encrypt::update(std::vector
<sal_uInt8
>& output
, std::vector
<sal_uInt8
>& input
, sal_uInt32 inputLength
)
217 int outputLength
= 0;
219 #if USE_TLS_OPENSSL + USE_TLS_NSS > 0
220 sal_uInt32 actualInputLength
= inputLength
== 0 || inputLength
> input
.size() ? input
.size() : inputLength
;
228 (void)EVP_EncryptUpdate(&mContext
, output
.data(), &outputLength
, input
.data(), actualInputLength
);
229 #endif // USE_TLS_OPENSSL
232 (void)PK11_CipherOp(mContext
, output
.data(), &outputLength
, actualInputLength
, input
.data(), actualInputLength
);
233 #endif // USE_TLS_NSS
235 return static_cast<sal_uInt32
>(outputLength
);
241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */