# HG changeset patch # User Olaf Wintermann # Date 1748600295 -7200 # Node ID 2c316612f6483c418d1655e0fce7d3321246ce1a # Parent 36a46311e0f621aad80d9b39c0f02d9cbb3d229c add crypto cng hashing implementation for windows diff -r 36a46311e0f6 -r 2c316612f648 src/server/util/hashing.c --- a/src/server/util/hashing.c Fri May 30 12:07:10 2025 +0200 +++ b/src/server/util/hashing.c Fri May 30 12:18:15 2025 +0200 @@ -214,3 +214,92 @@ #endif // WS_USE_CRYPTO_COMMON +#ifdef WS_USE_CRYPTO_CNG + +static int cng_hash_init(WinBCryptSHACTX *ctx, LPCWSTR algId) { + if(BCryptOpenAlgorithmProvider(&ctx->hAlg, algId, NULL, 0)) { + return 1; + } + + ULONG hashObjectLen; + ULONG result; + if(BCryptGetProperty(ctx->hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&hashObjectLen, sizeof(DWORD), &result, 0)) { + cng_cleanup(ctx->hAlg, NULL, NULL, NULL); + return 1; + } + + ctx->pbHashObject = calloc(1, hashObjectLen); + if(!ctx->pbHashObject) { + cng_cleanup(ctx->hAlg, NULL, NULL, NULL); + return 1; + } + + if(BCryptCreateHash(ctx->hAlg, &ctx->hHash, ctx->pbHashObject, hashObjectLen, NULL, 0, 0)) { + cng_cleanup(ctx->hAlg, NULL, ctx->hHash, ctx->pbHashObject); + return 1; + } + + return 0; +} + +static void cng_cleanup(BCRYPT_ALG_HANDLE hAesAlg, BCRYPT_KEY_HANDLE hKey, BCRYPT_HASH_HANDLE hHash, void *pbObject) { + if(hAesAlg) { + BCryptCloseAlgorithmProvider(hAesAlg,0); + } + if(hKey) { + BCryptDestroyKey(hKey); + } + if(hHash) { + BCryptDestroyHash(hHash); + } + if(pbObject) { + free(pbObject); + } +} + +int ws_sha1_init(WS_SHA1_CTX *ctx) { + return cng_hash_init(ctx, BCRYPT_SHA1_ALGORITHM); +} + +void ws_sha1_update(WS_SHA1_CTX *ctx, const char *data, size_t len) { + BCryptHashData(ctx->hHash, (PUCHAR)data, len, 0); +} + +void ws_sha1_final(WS_SHA1_CTX *ctx, unsigned char *buf) { + BCryptFinishHash(ctx->hHash, (PUCHAR)buf, DAV_SHA256_DIGEST_LENGTH, 0); + + // cleanup + cng_cleanup(ctx->hAlg, NULL, ctx->hHash, ctx->pbHashObject); +} + +int ws_sha256_init(WS_SHA256_CTX *ctx) { + return cng_hash_init(ctx, BCRYPT_SHA256_ALGORITHM); +} + +void ws_sha256_update(WS_SHA256_CTX *ctx, const char *data, size_t len) { + BCryptHashData(ctx->hHash, (PUCHAR)data, len, 0); +} + +void ws_sha256_final(WS_SHA256_CTX *ctx, unsigned char *buf) { + BCryptFinishHash(ctx->hHash, (PUCHAR)buf, DAV_SHA256_DIGEST_LENGTH, 0); + + // cleanup + cng_cleanup(ctx->hAlg, NULL, ctx->hHash, ctx->pbHashObject); +} + +int ws_sha512_init(WS_SHA512_CTX *ctx) { + return cng_hash_init(ctx, BCRYPT_SHA512_ALGORITHM); +} + +void ws_sha512_update(WS_SHA512_CTX *ctx, const char *data, size_t len) { + BCryptHashData(ctx->hHash, (PUCHAR)data, len, 0); +} + +void ws_sha512_final(WS_SHA512_CTX *ctx, unsigned char *buf) { + BCryptFinishHash(ctx->hHash, (PUCHAR)buf, DAV_SHA256_DIGEST_LENGTH, 0); + + // cleanup + cng_cleanup(ctx->hAlg, NULL, ctx->hHash, ctx->pbHashObject); +} + +#endif // WS_USE_CRYPTO_CNG