add crypto cng hashing implementation for windows

Fri, 30 May 2025 12:18:15 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 30 May 2025 12:18:15 +0200
changeset 595
2c316612f648
parent 594
36a46311e0f6
child 596
dc7cfde0f3bc

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

mercurial