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 <com/sun/star/uno/RuntimeException.hpp>
19 Crypto::Crypto(CryptoType type
)
28 // Initialize NSS, database functions are not needed
36 EVP_CIPHER_CTX_cleanup( &mContext
);
39 PK11_DestroyContext( mContext
, PR_TRUE
);
40 PK11_FreeSymKey( mSymKey
);
41 SECITEM_FreeItem( mSecParam
, PR_TRUE
);
46 const EVP_CIPHER
* Crypto::getCipher(CryptoType type
)
51 return EVP_aes_128_ecb();
53 return EVP_aes_128_cbc();
55 return EVP_aes_256_cbc();
64 void Crypto::setupContext(vector
<sal_uInt8
>& key
, vector
<sal_uInt8
>& iv
, CryptoType type
, CK_ATTRIBUTE_TYPE operation
)
66 CK_MECHANISM_TYPE mechanism
= static_cast<CK_ULONG
>(-1);
69 ivItem
.type
= siBuffer
;
74 ivItem
.len
= iv
.size();
76 SECItem
* pIvItem
= NULL
;
81 mechanism
= CKM_AES_ECB
;
84 mechanism
= CKM_AES_CBC
;
88 mechanism
= CKM_AES_CBC
;
95 PK11SlotInfo
* pSlot( PK11_GetBestSlot( mechanism
, NULL
) );
98 throw css::uno::RuntimeException("NSS Slot failure", css::uno::Reference
<css::uno::XInterface
>());
101 keyItem
.type
= siBuffer
;
102 keyItem
.data
= &key
[0];
103 keyItem
.len
= key
.size();
105 mSymKey
= PK11_ImportSymKey( pSlot
, mechanism
, PK11_OriginUnwrap
, CKA_ENCRYPT
, &keyItem
, NULL
);
106 mSecParam
= PK11_ParamFromIV( mechanism
, pIvItem
);
107 mContext
= PK11_CreateContextBySymKey( mechanism
, operation
, mSymKey
, mSecParam
);
109 #endif // USE_TLS_NSS
113 Decrypt::Decrypt(vector
<sal_uInt8
>& key
, vector
<sal_uInt8
>& iv
, CryptoType type
) :
117 EVP_CIPHER_CTX_init( &mContext
);
119 const EVP_CIPHER
* cipher
= getCipher(type
);
122 EVP_DecryptInit_ex( &mContext
, cipher
, NULL
, &key
[0], 0 );
124 EVP_DecryptInit_ex( &mContext
, cipher
, NULL
, &key
[0], &iv
[0] );
125 EVP_CIPHER_CTX_set_padding( &mContext
, 0 );
129 setupContext(key
, iv
, type
, CKA_DECRYPT
);
130 #endif // USE_TLS_NSS
133 sal_uInt32
Decrypt::update(vector
<sal_uInt8
>& output
, vector
<sal_uInt8
>& input
, sal_uInt32 inputLength
)
135 int outputLength
= 0;
137 sal_uInt32 actualInputLength
= inputLength
== 0 || inputLength
> input
.size() ? input
.size() : inputLength
;
140 (void)EVP_DecryptUpdate( &mContext
, &output
[0], &outputLength
, &input
[0], actualInputLength
);
141 #endif // USE_TLS_OPENSSL
144 (void)PK11_CipherOp( mContext
, &output
[0], &outputLength
, actualInputLength
, &input
[0], actualInputLength
);
145 #endif // USE_TLS_NSS
147 return static_cast<sal_uInt32
>(outputLength
);
150 sal_uInt32
Decrypt::aes128ecb(vector
<sal_uInt8
>& output
, vector
<sal_uInt8
>& input
, vector
<sal_uInt8
>& key
)
152 sal_uInt32 outputLength
= 0;
153 vector
<sal_uInt8
> iv
;
154 Decrypt
crypto(key
, iv
, Crypto::AES_128_ECB
);
155 outputLength
= crypto
.update(output
, input
);
161 Encrypt::Encrypt(vector
<sal_uInt8
>& key
, vector
<sal_uInt8
>& iv
, CryptoType type
) :
165 EVP_CIPHER_CTX_init( &mContext
);
167 const EVP_CIPHER
* cipher
= getCipher(type
);
170 EVP_EncryptInit_ex( &mContext
, cipher
, NULL
, &key
[0], 0 );
172 EVP_EncryptInit_ex( &mContext
, cipher
, NULL
, &key
[0], &iv
[0] );
173 EVP_CIPHER_CTX_set_padding( &mContext
, 0 );
177 setupContext(key
, iv
, type
, CKA_ENCRYPT
);
178 #endif // USE_TLS_NSS
181 sal_uInt32
Encrypt::update(vector
<sal_uInt8
>& output
, vector
<sal_uInt8
>& input
, sal_uInt32 inputLength
)
183 int outputLength
= 0;
185 sal_uInt32 actualInputLength
= inputLength
== 0 || inputLength
> input
.size() ? input
.size() : inputLength
;
188 (void)EVP_EncryptUpdate( &mContext
, &output
[0], &outputLength
, &input
[0], actualInputLength
);
189 #endif // USE_TLS_OPENSSL
192 (void)PK11_CipherOp( mContext
, &output
[0], &outputLength
, actualInputLength
, &input
[0], actualInputLength
);
193 #endif // USE_TLS_NSS
195 return static_cast<sal_uInt32
>(outputLength
);
201 const sal_uInt32
Digest::DIGEST_LENGTH_SHA1
= SHA_DIGEST_LENGTH
;
202 const sal_uInt32
Digest::DIGEST_LENGTH_SHA512
= SHA512_DIGEST_LENGTH
;
205 const sal_uInt32
Digest::DIGEST_LENGTH_SHA1
= SHA1_LENGTH
;
206 const sal_uInt32
Digest::DIGEST_LENGTH_SHA512
= SHA512_LENGTH
;
213 const EVP_MD
* lclOpenSSLgetEngine(Digest::DigestType eType
)
229 HASH_HashType
lclNSSgetHashType(Digest::DigestType eType
)
236 return HASH_AlgSHA512
;
246 Digest::Digest(DigestType eType
) :
250 mpContext
= EVP_MD_CTX_create();
251 EVP_DigestInit_ex(mpContext
, lclOpenSSLgetEngine(eType
), NULL
);
256 mpContext
= HASH_Create(lclNSSgetHashType(eType
));
257 HASH_Begin(mpContext
);
265 EVP_MD_CTX_destroy(mpContext
);
270 HASH_Destroy(mpContext
);
274 sal_uInt32
Digest::getLength()
279 return DIGEST_LENGTH_SHA1
;
281 return DIGEST_LENGTH_SHA512
;
288 bool Digest::update(std::vector
<sal_uInt8
>& input
)
291 EVP_DigestUpdate(mpContext
, &input
[0], input
.size());
294 HASH_Update(mpContext
, &input
[0], input
.size());
299 bool Digest::finalize(std::vector
<sal_uInt8
>& digest
)
304 unsigned int digestWrittenLength
;
305 digest
.resize(getLength(), 0);
306 EVP_DigestFinal_ex(mpContext
, &digest
[0], &digestWrittenLength
);
310 unsigned int digestWrittenLength
;
311 unsigned int digestLength
= static_cast<unsigned int>(getLength());
312 digest
.resize(digestLength
, 0);
313 HASH_End(mpContext
, &digest
[0], &digestWrittenLength
, digestLength
);
318 bool Digest::sha1(vector
<sal_uInt8
>& output
, vector
<sal_uInt8
>& input
)
320 bool aResult
= false;
322 Digest
aDigest(SHA1
);
323 aDigest
.update(input
);
324 aDigest
.finalize(output
);
329 bool Digest::sha512(vector
<sal_uInt8
>& output
, vector
<sal_uInt8
>& input
)
331 bool aResult
= false;
333 Digest
aDigest(SHA512
);
334 aDigest
.update(input
);
335 aDigest
.finalize(output
);
343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */