40 #define WIN32_LEAN_AND_MEAN
47 #pragma comment(lib, "bcrypt.lib")
84 #if !defined(WINCE) && !defined(__MINGW32__)
85 #define HAS_BCRYPTDERIVEKEYPBKDF2
88 #ifdef HAS_BCRYPTDERIVEKEYPBKDF2
92 BCRYPT_ALG_HANDLE hAlgorithm =
NULL;
95 if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_SHA1_ALGORITHM,
NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG))) {
99 result = BCRYPT_SUCCESS(BCryptDeriveKeyPBKDF2(hAlgorithm, (PUCHAR)
key, (
ULONG)key_length, (PUCHAR)salt, salt_length, iterations,
output, output_length, 0));
101 BCryptCloseAlgorithmProvider(hAlgorithm, 0);
110 #define DIGEST_SIZE 20
111 #define BLOCK_SIZE 64
114 BCRYPT_ALG_HANDLE hAlgorithm;
115 BCRYPT_HASH_HANDLE hInnerHash;
116 BCRYPT_HASH_HANDLE hOuterHash;
123 hmacFree(PRF_CTX *pContext) {
124 if (pContext->hOuterHash)
125 BCryptDestroyHash(pContext->hOuterHash);
126 if (pContext->hInnerHash)
127 BCryptDestroyHash(pContext->hInnerHash);
128 free(pContext->pbOuterHash);
129 free(pContext->pbInnerHash);
130 if (pContext->hAlgorithm)
131 BCryptCloseAlgorithmProvider(pContext->hAlgorithm, 0);
135 hmacPrecomputeDigest(BCRYPT_HASH_HANDLE hHash, PUCHAR pbPassword,
DWORD cbPassword,
BYTE mask) {
145 for (
i = 0;
i < cbPassword; ++
i) {
149 return BCRYPT_SUCCESS(BCryptHashData(hHash,
buffer,
sizeof(
buffer), 0));
153 hmacInit(PRF_CTX *pContext, PUCHAR pbPassword,
DWORD cbPassword) {
154 BOOL bStatus =
FALSE;
158 if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&pContext->hAlgorithm, BCRYPT_SHA1_ALGORITHM,
NULL, 0)) || !BCRYPT_SUCCESS(BCryptGetProperty(pContext->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&pContext->cbHashObject,
sizeof(pContext->cbHashObject), &cbResult, 0)) || ((pContext->pbInnerHash =
malloc(pContext->cbHashObject)) ==
NULL) || ((pContext->pbOuterHash =
malloc(pContext->cbHashObject)) ==
NULL) || !BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &pContext->hInnerHash, pContext->pbInnerHash, pContext->cbHashObject,
NULL, 0, 0)) || !BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &pContext->hOuterHash, pContext->pbOuterHash, pContext->cbHashObject,
NULL, 0, 0))) {
163 BCRYPT_HASH_HANDLE hHash =
NULL;
164 PUCHAR pbHashObject =
malloc(pContext->cbHashObject);
165 if (pbHashObject ==
NULL) {
169 bStatus = BCRYPT_SUCCESS(BCryptCreateHash(pContext->hAlgorithm, &hHash, pbHashObject, pContext->cbHashObject,
NULL, 0, 0)) && BCRYPT_SUCCESS(BCryptHashData(hHash, pbPassword, cbPassword, 0)) && BCRYPT_SUCCESS(BCryptGetProperty(hHash, BCRYPT_HASH_LENGTH, (PUCHAR)&cbPassword,
sizeof(cbPassword), &cbResult, 0)) && BCRYPT_SUCCESS(BCryptFinishHash(hHash,
key, cbPassword, 0));
172 BCryptDestroyHash(hHash);
182 bStatus = hmacPrecomputeDigest(pContext->hInnerHash, pbPassword, cbPassword, 0x36) && hmacPrecomputeDigest(pContext->hOuterHash, pbPassword, cbPassword, 0x5C);
186 if (bStatus ==
FALSE)
193 hmacCalculateInternal(BCRYPT_HASH_HANDLE hHashTemplate, PUCHAR pbData,
DWORD cbData, PUCHAR pbOutput,
DWORD cbOutput,
DWORD cbHashObject) {
194 BOOL success =
FALSE;
195 BCRYPT_HASH_HANDLE hHash =
NULL;
196 PUCHAR pbHashObject =
malloc(cbHashObject);
198 if (pbHashObject ==
NULL) {
202 if (BCRYPT_SUCCESS(BCryptDuplicateHash(hHashTemplate, &hHash, pbHashObject, cbHashObject, 0))) {
203 success = BCRYPT_SUCCESS(BCryptHashData(hHash, pbData, cbData, 0)) && BCRYPT_SUCCESS(BCryptFinishHash(hHash, pbOutput, cbOutput, 0));
205 BCryptDestroyHash(hHash);
214 hmacCalculate(PRF_CTX *pContext, PUCHAR pbData,
DWORD cbData, PUCHAR pbDigest) {
218 return BCRYPT_SUCCESS(BCryptGetProperty(pContext->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&cbHashObject,
sizeof(cbHashObject), &cbResult, 0)) && hmacCalculateInternal(pContext->hInnerHash, pbData, cbData, pbDigest, DIGEST_SIZE, cbHashObject) && hmacCalculateInternal(pContext->hOuterHash, pbDigest, DIGEST_SIZE, pbDigest, DIGEST_SIZE, cbHashObject);
222 myxor(LPBYTE ptr1, LPBYTE ptr2,
DWORD dwLen) {
228 pbkdf2(PUCHAR pbPassword,
ULONG cbPassword, PUCHAR pbSalt,
ULONG cbSalt,
DWORD cIterations, PUCHAR pbDerivedKey,
ULONG cbDerivedKey) {
229 BOOL bStatus =
FALSE;
231 BYTE Ti[DIGEST_SIZE];
233 LPBYTE U =
malloc(
max((cbSalt + 4), DIGEST_SIZE));
234 PRF_CTX prfCtx = {0};
240 if (pbPassword ==
NULL || cbPassword == 0 || pbSalt ==
NULL || cbSalt == 0 || cIterations == 0 || pbDerivedKey ==
NULL || cbDerivedKey == 0) {
245 if (!hmacInit(&prfCtx, pbPassword, cbPassword)) {
249 l = (
DWORD)ceil((
double)cbDerivedKey / (double)DIGEST_SIZE);
250 r = cbDerivedKey - (l - 1) * DIGEST_SIZE;
252 for (
i = 1;
i <= l;
i++) {
253 ZeroMemory(Ti, DIGEST_SIZE);
254 for (j = 0; j < cIterations; j++) {
257 memcpy(U, pbSalt, cbSalt);
258 U[cbSalt] = (
BYTE)((
i & 0xFF000000) >> 24);
259 U[cbSalt + 1] = (
BYTE)((
i & 0x00FF0000) >> 16);
260 U[cbSalt + 2] = (
BYTE)((
i & 0x0000FF00) >> 8);
261 U[cbSalt + 3] = (
BYTE)((
i & 0x000000FF));
266 dwULen = DIGEST_SIZE;
269 if (!hmacCalculate(&prfCtx, U, dwULen,
V)) {
273 myxor(Ti,
V, DIGEST_SIZE);
277 memcpy(&pbDerivedKey[(
i - 1) * DIGEST_SIZE], Ti, DIGEST_SIZE);
281 memcpy(&pbDerivedKey[(
i - 1) * DIGEST_SIZE], Ti,
r);
296 return (key_length <=
ZIP_UINT32_MAX) && pbkdf2((PUCHAR)
key, (
ULONG)key_length, (PUCHAR)salt, salt_length, iterations,
output, output_length);
314 ULONG key_length = key_size / 8;
321 if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&aes->hAlgorithm, BCRYPT_AES_ALGORITHM,
NULL, 0))) {
326 if (!BCRYPT_SUCCESS(BCryptSetProperty(aes->hAlgorithm, BCRYPT_CHAINING_MODE, (PUCHAR)BCRYPT_CHAIN_MODE_ECB,
sizeof(BCRYPT_CHAIN_MODE_ECB), 0))) {
331 if (!BCRYPT_SUCCESS(BCryptGetProperty(aes->hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&aes->cbKeyObject,
sizeof(aes->cbKeyObject), &cbResult, 0))) {
336 aes->pbKeyObject =
malloc(aes->cbKeyObject);
337 if (aes->pbKeyObject ==
NULL) {
343 if (!BCRYPT_SUCCESS(BCryptGenerateSymmetricKey(aes->hAlgorithm, &aes->hKey, aes->pbKeyObject, aes->cbKeyObject, (PUCHAR)
key, key_length, 0))) {
357 if (aes->hKey !=
NULL) {
358 BCryptDestroyKey(aes->hKey);
361 if (aes->pbKeyObject !=
NULL) {
362 free(aes->pbKeyObject);
365 if (aes->hAlgorithm !=
NULL) {
366 BCryptCloseAlgorithmProvider(aes->hAlgorithm, 0);
376 return BCRYPT_SUCCESS(
status);
408 status = BCryptOpenAlgorithmProvider(&hmac->
hAlgorithm, BCRYPT_SHA1_ALGORITHM,
NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG);
409 if (!BCRYPT_SUCCESS(
status)) {
415 if (!BCRYPT_SUCCESS(
status)) {
428 if (!BCRYPT_SUCCESS(
status)) {
441 if (!BCRYPT_SUCCESS(
status)) {
456 BCryptDestroyHash(hmac->
hHash);
468 BCryptCloseAlgorithmProvider(hmac->
hAlgorithm, 0);
489 return BCRYPT_SUCCESS(BCryptFinishHash(hmac->
hHash, data, hmac->
cbHash, 0));
494 return BCRYPT_SUCCESS(BCryptGenRandom(
NULL,
buffer,
length, BCRYPT_USE_SYSTEM_PREFERRED_RNG));
const lzma_allocator const uint8_t * in
const lzma_allocator const uint8_t size_t uint8_t * out
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
RZ_API void Ht_() free(HtName_(Ht) *ht)
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int)
void * malloc(size_t size)
void * calloc(size_t number, size_t size)
static const char struct stat static buf struct stat static buf static vhangup int status
BCRYPT_ALG_HANDLE hAlgorithm
BCRYPT_ALG_HANDLE hAlgorithm
#define V(handle, symbol)
void error(const char *msg)
#define ZIP_CRYPTO_AES_BLOCK_LENGTH
bool _zip_crypto_hmac(_zip_crypto_hmac_t *hmac, zip_uint8_t *data, zip_uint64_t length)
bool _zip_crypto_hmac_output(_zip_crypto_hmac_t *hmac, zip_uint8_t *data)
bool _zip_crypto_pbkdf2(const zip_uint8_t *key, zip_uint64_t key_length, const zip_uint8_t *salt, zip_uint16_t salt_length, zip_uint16_t iterations, zip_uint8_t *output, zip_uint16_t output_length)
bool _zip_crypto_aes_encrypt_block(_zip_crypto_aes_t *aes, const zip_uint8_t *in, zip_uint8_t *out)
void _zip_crypto_hmac_free(_zip_crypto_hmac_t *hmac)
void _zip_crypto_aes_free(_zip_crypto_aes_t *aes)
_zip_crypto_aes_t * _zip_crypto_aes_new(const zip_uint8_t *key, zip_uint16_t key_size, zip_error_t *error)
ZIP_EXTERN bool zip_secure_random(zip_uint8_t *buffer, zip_uint16_t length)
_zip_crypto_hmac_t * _zip_crypto_hmac_new(const zip_uint8_t *secret, zip_uint64_t secret_length, zip_error_t *error)