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
);
37 PK11_DestroyContext( mContext
, PR_TRUE
);
38 PK11_FreeSymKey( mSymKey
);
39 SECITEM_FreeItem( mSecParam
, PR_TRUE
);
44 const EVP_CIPHER
* Crypto::getCipher(CryptoType type
)
49 return EVP_aes_128_ecb();
51 return EVP_aes_128_cbc();
53 return EVP_aes_256_cbc();
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);
67 ivItem
.type
= siBuffer
;
69 ivItem
.data
= nullptr;
71 ivItem
.data
= iv
.data();
72 ivItem
.len
= iv
.size();
74 SECItem
* pIvItem
= nullptr;
79 mechanism
= CKM_AES_ECB
;
82 mechanism
= CKM_AES_CBC
;
86 mechanism
= CKM_AES_CBC
;
93 PK11SlotInfo
* pSlot(PK11_GetBestSlot(mechanism
, nullptr));
96 throw css::uno::RuntimeException("NSS Slot failure", css::uno::Reference
<css::uno::XInterface
>());
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
111 Decrypt::Decrypt(std::vector
<sal_uInt8
>& key
, std::vector
<sal_uInt8
>& iv
, CryptoType type
)
115 EVP_CIPHER_CTX_init(&mContext
);
117 const EVP_CIPHER
* cipher
= getCipher(type
);
120 EVP_DecryptInit_ex(&mContext
, cipher
, nullptr, key
.data(), 0);
122 EVP_DecryptInit_ex(&mContext
, cipher
, nullptr, key
.data(), iv
.data());
123 EVP_CIPHER_CTX_set_padding(&mContext
, 0);
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
;
138 (void)EVP_DecryptUpdate(&mContext
, output
.data(), &outputLength
, input
.data(), actualInputLength
);
139 #endif // USE_TLS_OPENSSL
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
);
159 Encrypt::Encrypt(std::vector
<sal_uInt8
>& key
, std::vector
<sal_uInt8
>& iv
, CryptoType type
)
163 EVP_CIPHER_CTX_init(&mContext
);
165 const EVP_CIPHER
* cipher
= getCipher(type
);
168 EVP_EncryptInit_ex(&mContext
, cipher
, nullptr, key
.data(), 0);
170 EVP_EncryptInit_ex(&mContext
, cipher
, nullptr, key
.data(), iv
.data());
171 EVP_CIPHER_CTX_set_padding(&mContext
, 0);
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
;
186 (void)EVP_EncryptUpdate(&mContext
, output
.data(), &outputLength
, input
.data(), actualInputLength
);
187 #endif // USE_TLS_OPENSSL
190 (void)PK11_CipherOp(mContext
, output
.data(), &outputLength
, actualInputLength
, input
.data(), actualInputLength
);
191 #endif // USE_TLS_NSS
193 return static_cast<sal_uInt32
>(outputLength
);
199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */