int KSI_HmacHasher_reset(KSI_HmacHasher *hasher) { int res = KSI_UNKNOWN_ERROR; if (hasher == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } KSI_ERR_clearErrors(hasher->ctx); res = KSI_DataHasher_reset(hasher->dataHasher); if (res != KSI_OK) { KSI_pushError(hasher->ctx, res, NULL); goto cleanup; } /* Hash inner data. */ KSI_LOG_logBlob(hasher->ctx, KSI_LOG_DEBUG, "Adding ipad", hasher->ipadXORkey, hasher->blockSize); res = KSI_DataHasher_add(hasher->dataHasher, hasher->ipadXORkey, hasher->blockSize); if (res != KSI_OK) { KSI_pushError(hasher->ctx, res, NULL); goto cleanup; } res = KSI_OK; cleanup: return res; }
int KSI_DataHasher_open(KSI_CTX *ctx, KSI_HashAlgorithm algo_id, KSI_DataHasher **hasher) { int res = KSI_UNKNOWN_ERROR; KSI_DataHasher *tmp_hasher = NULL; CRYPTO_HASH_CTX *tmp_cryptoCTX = NULL; HCRYPTPROV tmp_CSP = 0; KSI_ERR_clearErrors(ctx); if (ctx == NULL || hasher == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } /*Test if hash algorithm is valid*/ if (!KSI_isHashAlgorithmSupported(algo_id)) { KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, NULL); goto cleanup; } /*Create new abstract data hasher object*/ tmp_hasher = KSI_new(KSI_DataHasher); if (tmp_hasher == NULL) { KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL); goto cleanup; } tmp_hasher->hashContext = NULL; tmp_hasher->ctx = ctx; tmp_hasher->algorithm = algo_id; tmp_hasher->closeExisting = closeExisting; /*Create new helper context for crypto api*/ res = CRYPTO_HASH_CTX_new(&tmp_cryptoCTX); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } /*Create new crypto service provider (CSP)*/ if (!CryptAcquireContext(&tmp_CSP, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){ char errm[1024]; KSI_snprintf(errm, sizeof(errm), "Wincrypt Error (%d)", GetLastError()); KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, errm); goto cleanup; } /*Set CSP in helper struct*/ tmp_cryptoCTX->pt_CSP = tmp_CSP; /*Set helper struct in abstract struct*/ tmp_hasher->hashContext = tmp_cryptoCTX; res = KSI_DataHasher_reset(tmp_hasher); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } *hasher = tmp_hasher; tmp_hasher = NULL; tmp_cryptoCTX = NULL; tmp_CSP = 0; res = KSI_OK; cleanup: KSI_DataHasher_free(tmp_hasher); if (tmp_CSP) CryptReleaseContext(tmp_CSP, 0); CRYPTO_HASH_CTX_free(tmp_cryptoCTX); return res; }
int KSI_HmacHasher_close(KSI_HmacHasher *hasher, KSI_DataHash **hmac) { int res = KSI_UNKNOWN_ERROR; KSI_DataHash *innerHash = NULL; KSI_DataHash *outerHash = NULL; const unsigned char *digest = NULL; size_t digest_len = 0; if (hasher == NULL || hmac == NULL) { res = KSI_INVALID_ARGUMENT; goto cleanup; } KSI_ERR_clearErrors(hasher->ctx); KSI_LOG_debug(hasher->ctx, "Closing inner hasher"); res = KSI_DataHasher_close(hasher->dataHasher, &innerHash); if (res != KSI_OK) { KSI_pushError(hasher->ctx, res, NULL); goto cleanup; } /* Hash outer data. */ res = KSI_DataHasher_reset(hasher->dataHasher); if (res != KSI_OK) { KSI_pushError(hasher->ctx, res, NULL); goto cleanup; } KSI_LOG_logBlob(hasher->ctx, KSI_LOG_DEBUG, "Adding opad", hasher->opadXORkey, hasher->blockSize); res = KSI_DataHasher_add(hasher->dataHasher, hasher->opadXORkey, hasher->blockSize); if (res != KSI_OK) { KSI_pushError(hasher->ctx, res, NULL); goto cleanup; } res = KSI_DataHash_extract(innerHash, NULL, &digest, &digest_len); if (res != KSI_OK) { KSI_pushError(hasher->ctx, res, NULL); goto cleanup; } KSI_LOG_logBlob(hasher->ctx, KSI_LOG_DEBUG, "Adding inner hash", digest, digest_len); res = KSI_DataHasher_add(hasher->dataHasher, digest, digest_len); if (res != KSI_OK) { KSI_pushError(hasher->ctx, res, NULL); goto cleanup; } KSI_LOG_debug(hasher->ctx, "Closing outer hasher"); res = KSI_DataHasher_close(hasher->dataHasher, &outerHash); if (res != KSI_OK) { KSI_pushError(hasher->ctx, res, NULL); goto cleanup; } *hmac = KSI_DataHash_ref(outerHash); res = KSI_OK; cleanup: KSI_DataHash_free(innerHash); KSI_DataHash_free(outerHash); return res; }