// bcrypt-test.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <wincompat.h>
#include <bcrypt.h>
#include <stdio.h>
#include "picotls/ptlsbcrypt.h"
#include "picotls/minicrypto.h"

int KeyInit(BCRYPT_KEY_HANDLE *hKey, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz, const BYTE *proposedKey,
            DWORD proposedKeyLength, BYTE **ko, ULONG *ko_length)
{
    DWORD cbData = 0;
    HANDLE hAlgo = NULL;

    // Open an algorithm handle.
    NTSTATUS ret = BCryptOpenAlgorithmProvider(&hAlgo, name, NULL, 0);

    if (BCRYPT_SUCCESS(ret)) {
        // Set the properties to define the chaining mode
        ret = BCryptSetProperty(hAlgo, BCRYPT_CHAINING_MODE, (PBYTE)chain_mode, (ULONG)chain_mode_sz, 0);
    }

    *ko = NULL;
    *ko_length = 0;

    if (BCRYPT_SUCCESS(ret)) {
        DWORD ko_size = 0;
        ULONG cbResult = 0;

        ret = BCryptGetProperty(hAlgo, BCRYPT_OBJECT_LENGTH, (PUCHAR)&ko_size, (ULONG)sizeof(ko_size), &cbResult, 0);

        if (BCRYPT_SUCCESS(ret)) {
            *ko = (uint8_t *)malloc(ko_size);
            if (*ko == NULL) {
                ret = STATUS_NO_MEMORY;
            } else {
                *ko_length = ko_size;
                memset(*ko, 0, *ko_length);
            }
        }
    }

    if (BCRYPT_SUCCESS(ret)) {
        // Generate the key from supplied input key bytes.
        ret = BCryptGenerateSymmetricKey(hAlgo, hKey, *ko, *ko_length, (PBYTE)proposedKey, proposedKeyLength, 0);
    } else {
        if (*ko != NULL) {
            free(*ko);
            *ko = NULL;
            *ko_length = 0;
        }
    }

    if (hAlgo != NULL) {
        BCryptCloseAlgorithmProvider(hAlgo, 0);
    }

    return BCRYPT_SUCCESS(ret) ? 0 : -1;
}

void KeyRelease(BCRYPT_KEY_HANDLE *hKey, BYTE **ko, ULONG *ko_length)
{
    BCryptDestroyKey(*hKey);
    *hKey = NULL;
    if (*ko) {
        free(*ko);
    }
    *ko = NULL;
    *ko_length = 0;
}

int EncodeOneShot(wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz, BYTE *key, ULONG key_length, BYTE *data,
                  ULONG dataLength, BYTE *nonceValue, ULONG nonceLength, BYTE *authData, ULONG authDataLength, ULONG authTagLength,
                  BYTE *encrypted, ULONG encryptedLengthMax, ULONG *encryptedLength)
{

    BCRYPT_KEY_HANDLE hKey = NULL;
    BYTE *authTag = encrypted + dataLength;
    BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO bacmi;
    BYTE *ko = NULL;
    ULONG ko_length = 0;
    int ret = 0;

    *encryptedLength = 0;

    if (KeyInit(&hKey, name, chain_mode, chain_mode_sz, key, key_length, &ko, &ko_length) != 0) {
        return -1;
    }

    memset(authTag, 0, authTagLength);
    // Set the auth mode info for AEAD
    BCRYPT_INIT_AUTH_MODE_INFO(bacmi);
    bacmi.pbNonce = nonceValue;
    bacmi.cbNonce = nonceLength;
    bacmi.pbAuthData = authData;
    bacmi.cbAuthData = authDataLength;
    bacmi.pbTag = authTag;
    bacmi.cbTag = authTagLength;
    /* All other fields are set to NULL by the INIT macro. */

    /* If called with a NULL pointer for the data block, we will merely compute the block size. */
    DWORD cbCipherText = 0;
    NTSTATUS status = BCryptEncrypt(hKey, data, dataLength, &bacmi, NULL, 0, encrypted, encryptedLengthMax, &cbCipherText, 0);

    KeyRelease(&hKey, &ko, &ko_length);

    if (BCRYPT_SUCCESS(status)) {
        *encryptedLength = cbCipherText + authTagLength;
    } else {
        ret = -1;
    }

    return ret;
}

int DecodeOneShot(wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz, BYTE *key, ULONG key_length, BYTE *encrypted,
                  ULONG encryptedLength, BYTE *nonceValue, ULONG nonceLength, BYTE *authData, ULONG authDataLength,
                  ULONG authTagLength, BYTE *decrypted, ULONG decryptedLengthMax, ULONG *decryptedLength)
{

    BCRYPT_KEY_HANDLE hKey = NULL;
    BYTE *authTag = encrypted + (encryptedLength - authTagLength);
    BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO bacmi;
    BYTE *ko = NULL;
    ULONG ko_length = 0;
    int ret = 0;

    *decryptedLength = 0;

    if (KeyInit(&hKey, name, chain_mode, chain_mode_sz, key, key_length, &ko, &ko_length) != 0) {
        return -1;
    }

    // Set the auth mode info for AEAD
    BCRYPT_INIT_AUTH_MODE_INFO(bacmi);
    bacmi.pbNonce = nonceValue;
    bacmi.cbNonce = nonceLength;
    bacmi.pbAuthData = authData;
    bacmi.cbAuthData = authDataLength;
    bacmi.pbTag = authTag;
    bacmi.cbTag = authTagLength;
    /* All other fields are set to NULL by the INIT macro. */

    /* If called with a NULL pointer for the data block, we will merely compute the block size. */
    DWORD cbCipherText = 0;
    NTSTATUS status = BCryptDecrypt(hKey, encrypted, encryptedLength - authTagLength, &bacmi, NULL, 0, decrypted,
                                    decryptedLengthMax, &cbCipherText, 0);

    KeyRelease(&hKey, &ko, &ko_length);

    if (BCRYPT_SUCCESS(status)) {
        *decryptedLength = cbCipherText;
    } else {
        ret = -1;
    }

    return ret;
}

int test_oneshot(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE data[123];
    BYTE nonce[12];
    BYTE authData[9];
    BYTE encrypted[256];
    ULONG encryptedLength;
    BYTE decrypted[256];
    ULONG decryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(nonce) >= aead->iv_size);
    assert(sizeof(data) + authTagLength <= sizeof(encrypted));
    assert(sizeof(decrypted) >= sizeof(encrypted));

    memset(key, 'k', sizeof(key));
    memset(data, 'd', sizeof(data));
    memset(nonce, 'n', sizeof(nonce));
    memset(authData, 'a', sizeof(authData));

    ret = EncodeOneShot(name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, data, 123, nonce, (ULONG)aead->iv_size,
                        authData, 9, authTagLength, encrypted, 256, &encryptedLength);

    printf("Encrypt one shot returns %d, l=%d\n", ret, encryptedLength);

    if (ret == 0) {
        ret = DecodeOneShot(name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, encrypted, encryptedLength, nonce,
                            (ULONG)aead->iv_size, authData, 9, authTagLength, decrypted, 256, &decryptedLength);

        printf("Decrypt one shot returns %d, l=%d\n", ret, decryptedLength);

        if (ret == 0) {
            if (decryptedLength != 123) {
                printf("Wrong length, not %d\n", 123);
                ret = -1;
            } else if (memcmp(data, decrypted, 123) != 0) {
                printf("Data and decrypted don't match\n");
                ret = -1;
            } else {
                printf("One shot matches.\n");
            }
        }
    }

    return ret;
}

void delete_test_aead_context(ptls_aead_context_t *ctx)
{
    if (ctx != NULL) {
        ctx->dispose_crypto(ctx);
        free(ctx);
    }
}

ptls_aead_context_t *new_test_aead_context(ptls_aead_algorithm_t *aead, int is_enc, BYTE *key)
{
    int ret = 0;
    ptls_aead_context_t *ctx = (ptls_aead_context_t *)malloc(aead->context_size);

    if (ctx != NULL) {
        memset(ctx, 0, aead->context_size);
        *ctx = (ptls_aead_context_t){aead};
        if (aead->setup_crypto(ctx, is_enc, key) != 0) {
            printf("For %s, setup returns %d\n", aead->name, ret);
            delete_test_aead_context(ctx);
            ctx = NULL;
        }
    } else {
        printf("For %s, memory error during setup\n", aead->name);
    }

    return (ctx);
}

int test_decrypt(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE data[123];
    BYTE nonce[12];
    BYTE authData[9];
    BYTE encrypted[256];
    ULONG encryptedLength;
    BYTE decrypted[256];
    size_t decryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    ptls_aead_context_t *ctx = NULL;
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(nonce) >= aead->iv_size);
    assert(sizeof(data) + authTagLength <= sizeof(encrypted));
    assert(sizeof(decrypted) >= sizeof(encrypted));

    memset(key, 'k', sizeof(key));
    memset(data, 'd', sizeof(data));
    memset(nonce, 'n', sizeof(nonce));
    memset(authData, 'a', sizeof(authData));

    /* Create a decryption context */
    ctx = new_test_aead_context(aead, 0, key);
    if (ctx == NULL) {
        ret = -1;
    }

    /* Do a simple encrypt using one shot bcrypt */
    if (ret == 0) {
        ret = EncodeOneShot(name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, data, 123, nonce, (ULONG)aead->iv_size,
                            authData, 9, authTagLength, encrypted, 256, &encryptedLength);
    }

    /* Try decrypt with library procedure */
    if (ret == 0) {
        decryptedLength = ctx->do_decrypt(ctx, decrypted, encrypted, encryptedLength, nonce, authData, 9);
        if (decryptedLength >= encryptedLength) {
            printf("For %s, decrypt returns %d\n", aead->name, (int)decryptedLength);
            ret = -1;
        } else if (decryptedLength != 123) {
            printf("For %s, decrypt returns %d instead of %d\n", aead->name, (int)decryptedLength, 123);
            ret = -1;
        } else if (memcmp(data, decrypted, decryptedLength) != 0) {
            printf("For %s, decrypted does not match clear text\n", aead->name);
            ret = -1;
        } else {
            printf("For %s, decrypting test passes.\n", aead->name);
        }
    }

    delete_test_aead_context(ctx);

    return ret;
}

int test_encrypt(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE data[123];
    BYTE nonce[12];
    BYTE authData[9];
    BYTE encryptedRef[256];
    ULONG encryptedRefLength;
    BYTE encrypted[256];
    size_t encryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    ptls_aead_context_t *ctx = NULL;
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(nonce) >= aead->iv_size);
    assert(sizeof(data) + authTagLength <= sizeof(encrypted));
    assert(sizeof(data) + authTagLength <= sizeof(encryptedRef));

    memset(key, 'k', sizeof(key));
    memset(data, 'd', sizeof(data));
    memset(nonce, 'n', sizeof(nonce));
    memset(authData, 'a', sizeof(authData));

    /* Create an encryption context */
    ctx = new_test_aead_context(aead, 1, key);
    if (ctx == NULL) {
        ret = -1;
    }

    /* Do a simple encrypt using one shot bcrypt */
    if (ret == 0) {
        ret = EncodeOneShot(name, chain_mode, chain_mode_sz, key, (ULONG)aead->key_size, data, 123, nonce, (ULONG)aead->iv_size,
                            authData, 9, authTagLength, encryptedRef, 256, &encryptedRefLength);
    }

    /* Try encrypt with library procedure */
    if (ret == 0) {
        ctx->do_encrypt_init(ctx, nonce, authData, 9);
        encryptedLength = ctx->do_encrypt_update(ctx, encrypted, data, 123);
        encryptedLength += ctx->do_encrypt_final(ctx, &encrypted[encryptedLength]);

        if (encryptedLength != encryptedRefLength) {
            printf("For %s, encrypt returns %d instead of %d\n", aead->name, (int)encryptedLength, encryptedRefLength);
            ret = -1;
        } else if (memcmp(encryptedRef, encrypted, encryptedRefLength) != 0) {
            printf("For %s, encrypted does not match ref\n", aead->name);
            for (ULONG i = 0; i < encryptedRefLength; i++) {
                if (encryptedRef[i] != encrypted[i]) {
                    printf("For %s, encrypted[%d] = 0x%02x vs encryptedRef[%d] = 0x%02x\n", aead->name, i, encrypted[i], i,
                           encryptedRef[i]);
                    break;
                }
            }
            ret = -1;
        } else {
            printf("For %s, encrypting test passes.\n", aead->name);
        }
    }

    delete_test_aead_context(ctx);

    return ret;
}

int test_for_size(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    BYTE key[32];
    BYTE nonce[12];
    BYTE authData[9];
    BYTE *data = NULL;
    BYTE *encrypted = NULL;
    BYTE *decrypted = NULL;
    size_t encryptedLength;
    size_t decryptedLength;
    ULONG authTagLength = (ULONG)aead->tag_size;
    ptls_aead_context_t *ctx_e = NULL;
    ptls_aead_context_t *ctx_d = NULL;
    ULONG packet_size[] = {1500, 128, 3, 0};
    ULONG nb_packet_size = (ULONG)(sizeof(packet_size) / sizeof(ULONG));
    int ret = 0;

    assert(sizeof(key) >= aead->key_size);
    assert(sizeof(nonce) >= aead->iv_size);

    memset(key, 'k', sizeof(key));
    memset(nonce, 'n', sizeof(nonce));
    memset(authData, 'a', sizeof(authData));

    /* Create the encryption contexts */
    ctx_e = new_test_aead_context(aead, 1, key);
    ctx_d = new_test_aead_context(aead, 0, key);

    if (ctx_e == NULL || ctx_d == NULL) {
        ret = -1;
    }

    /* Test a variety of packet sizes */
    for (ULONG i = 0; ret == 0 && i < nb_packet_size; i++) {
        ULONG data_size = (packet_size[i] > 0) ? packet_size[i] : 128;
        ULONG encrypted_size = packet_size[i] + authTagLength;

        data = (BYTE *)malloc(data_size);
        encrypted = (BYTE *)malloc(encrypted_size);
        decrypted = (BYTE *)malloc(data_size);

        if (data == NULL || encrypted == NULL || decrypted == NULL) {
            printf("For %s: cannot allocate memory for packet size[%d] = %d\n", aead->name, i, packet_size[i]);
        } else {
            memset(data, 'd', data_size);

            ctx_e->do_encrypt_init(ctx_e, nonce, authData, 9);
            encryptedLength = ctx_e->do_encrypt_update(ctx_e, encrypted, data, packet_size[i]);
            encryptedLength += ctx_e->do_encrypt_final(ctx_e, &encrypted[encryptedLength]);
            decryptedLength = ctx_d->do_decrypt(ctx_d, decrypted, encrypted, encryptedLength, nonce, authData, 9);

            if (decryptedLength >= encryptedLength) {
                printf("For %s, decrypt returns %d\n", aead->name, (int)decryptedLength);
                ret = -1;
            } else if (decryptedLength != packet_size[i]) {
                printf("For %s, decrypt returns %d instead of %d\n", aead->name, (int)decryptedLength, packet_size[i]);
                ret = -1;
            } else if (memcmp(data, decrypted, decryptedLength) != 0) {
                printf("For %s, decrypted does not match clear text\n", aead->name);
                ret = -1;
            } else {
                printf("For %s, test packet size[%d] = %d passes.\n", aead->name, i, packet_size[i]);
            }
        }

        if (data != NULL) {
            free(data);
            data = NULL;
        }

        if (encrypted != NULL) {
            free(encrypted);
            encrypted = NULL;
        }

        if (decrypted != NULL) {
            free(decrypted);
            decrypted = NULL;
        }
    }

    delete_test_aead_context(ctx_e);
    delete_test_aead_context(ctx_d);

    return ret;
}

int test_one_aead(ptls_aead_algorithm_t *aead, wchar_t *name, wchar_t *chain_mode, size_t chain_mode_sz)
{
    int ret = test_oneshot(aead, name, chain_mode, chain_mode_sz);

    printf("For %s, test one shot returns %d\n", aead->name, ret);

    if (ret == 0) {
        ret = test_decrypt(aead, name, chain_mode, chain_mode_sz);

        printf("For %s, test decrypt returns %d\n", aead->name, ret);
    }

    if (ret == 0) {
        ret = test_encrypt(aead, name, chain_mode, chain_mode_sz);

        printf("For %s, test encrypt returns %d\n", aead->name, ret);
    }

    if (ret == 0) {
        ret = test_for_size(aead, name, chain_mode, chain_mode_sz);

        printf("For %s, test packet sizes returns %d\n", aead->name, ret);
    }

    return ret;
}

/* Test of cipher functions.
 * The test verifies that a message encode with a bcrypt function can be
 * decoded with a minicrypto function, and vice versa.
 */

int test_cipher_one_way(char const *name1, char const *name2, ptls_cipher_algorithm_t *b1, ptls_cipher_algorithm_t *b2,
                        unsigned int nb_blocks)
{
    BYTE key[32];
    BYTE nonce[16];
    BYTE data[128];
    BYTE encrypted[128];
    BYTE decrypted[128];
    size_t data_size = b1->block_size * nb_blocks;
    ptls_cipher_context_t *ctx1 = NULL;
    ptls_cipher_context_t *ctx2 = NULL;
    int ret = 0;

    assert(sizeof(key) >= b1->key_size);
    assert(sizeof(data) >= data_size);
    assert(sizeof(nonce) >= b1->iv_size);

    memset(key, 'k', sizeof(key));
    memset(data, 'd', data_size);

    ctx1 = ptls_cipher_new(b1, 1, key);
    ctx2 = ptls_cipher_new(b2, 0, key);

    if (ctx1 == NULL || ctx2 == NULL) {
        ret = -1;
    } else {
        memset(nonce, 0, sizeof(nonce));
        if (ctx1->do_init != NULL) {
            ctx1->do_init(ctx1, nonce);
        }

        if (ctx2->do_init != NULL) {
            ctx2->do_init(ctx2, nonce);
        }

        ctx1->do_transform(ctx1, encrypted, data, data_size);
        ctx2->do_transform(ctx2, decrypted, encrypted, data_size);

        if (memcmp(data, decrypted, data_size) != 0) {
            printf("For %s -> %s, decrypted does not match clear text\n", name1, name2);
            ret = -1;
        } else {
            printf("For %s -> %s, test passes.\n", name1, name2);
        }
    }

    if (ctx1 != NULL) {
        ptls_cipher_free(ctx1);
    }

    if (ctx2 != NULL) {
        ptls_cipher_free(ctx2);
    }

    return ret;
}

int test_cipher_pair(char const *name1, char const *name2, ptls_cipher_algorithm_t *b1, ptls_cipher_algorithm_t *b2,
                     unsigned int nb_blocks)
{
    int ret = test_cipher_one_way(name1, name2, b1, b2, nb_blocks);

    if (ret == 0) {
        ret = test_cipher_one_way(name2, name1, b2, b1, nb_blocks);
    }

    return ret;
}

/* Test of the hash functions
 */

int test_hash_calc(char const *name1, char const *name2, ptls_hash_algorithm_t *h1, ptls_hash_algorithm_t *h2)
{
    BYTE data[123];
    BYTE tag1[128];
    BYTE tag2[128];
    ptls_hash_context_t *ctx1 = NULL;
    ptls_hash_context_t *ctx2 = NULL;
    int ret = 0;

    assert(sizeof(tag1) >= h1->digest_size);
    assert(sizeof(tag2) >= h2->digest_size);
    assert(h1->digest_size == h2->digest_size);

    memset(data, 'd', sizeof(data));
    memset(tag1, '1', sizeof(tag1));
    memset(tag2, '2', sizeof(tag2));

    if (h1->digest_size != h2->digest_size) {
        ret = -1;
    }
    if (ret == 0) {
        ret = ptls_calc_hash(h1, tag1, data, sizeof(data));
    }

    if (ret == 0) {
        ret = ptls_calc_hash(h2, tag2, data, sizeof(data));
    }

    if (ret == 0){
        if (memcmp(tag1, tag2, h1->digest_size) != 0) {
            printf("For %s -> %s, hash1 does not match hash2\n", name1, name2);
            ret = -1;
        } else {
            printf("For %s -> %s, hash test passes.\n", name1, name2);
        }
    }

    return ret;
}

/* Minimal test program for the bcrypt functions.
 * Need to add tests for the SHA256 and SHA384 implementations.
 */

int main()
{
    int ret = 0;

    ret |= test_cipher_pair("bcrypt aes128ecb", "minicrypto aes128ecb", &ptls_bcrypt_aes128ecb, &ptls_minicrypto_aes128ecb, 1);
    ret |= test_cipher_pair("bcrypt aes256ecb", "minicrypto aes256ecb", &ptls_bcrypt_aes256ecb, &ptls_minicrypto_aes256ecb, 1);

    ret |= test_cipher_pair("bcrypt aes128ctr", "minicrypto aes128ctr", &ptls_bcrypt_aes128ctr, &ptls_minicrypto_aes128ctr, 4);
    ret |= test_cipher_pair("bcrypt aes256ctr", "minicrypto aes256ctr", &ptls_bcrypt_aes256ctr, &ptls_minicrypto_aes256ctr, 4);
        
    ret |= test_one_aead(&ptls_bcrypt_aes128gcm, BCRYPT_AES_ALGORITHM, BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM));

    ret |= test_one_aead(&ptls_bcrypt_aes256gcm, BCRYPT_AES_ALGORITHM, BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM));

    ret |= test_hash_calc("bcrypt sha256", "minicrypto sha256", &ptls_bcrypt_sha256, &ptls_minicrypto_sha256);
    ret |= test_hash_calc("bcrypt sha384", "minicrypto sha384", &ptls_bcrypt_sha384, &ptls_minicrypto_sha384);

    exit(ret);
}
