Fri, 30 May 2025 12:18:15 +0200
add crypto cng hashing implementation for windows
| src/server/util/hashing.c | file | annotate | diff | comparison | revisions |
--- 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