/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include "pk11pub.h"
#include "secerr.h"
#include "nss.h"

static SECStatus
hex_to_byteval(const char *c2, unsigned char *byteval)
{
    int i;
    unsigned char offset;
    *byteval = 0;
    for (i = 0; i < 2; i++) {
        if (c2[i] >= '0' && c2[i] <= '9') {
            offset = c2[i] - '0';
            *byteval |= offset << 4 * (1 - i);
        } else if (c2[i] >= 'a' && c2[i] <= 'f') {
            offset = c2[i] - 'a';
            *byteval |= (offset + 10) << 4 * (1 - i);
        } else if (c2[i] >= 'A' && c2[i] <= 'F') {
            offset = c2[i] - 'A';
            *byteval |= (offset + 10) << 4 * (1 - i);
        } else {
            return SECFailure;
        }
    }
    return SECSuccess;
}

static SECStatus
aes_encrypt_buf(
    const unsigned char *key, unsigned int keysize,
    const unsigned char *iv, unsigned int ivsize,
    unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
    const unsigned char *input, unsigned int inputlen,
    const unsigned char *aad, unsigned int aadlen, unsigned int tagsize)
{
    SECStatus rv = SECFailure;
    SECItem key_item;
    PK11SlotInfo *slot = NULL;
    PK11SymKey *symKey = NULL;
    CK_GCM_PARAMS gcm_params;
    SECItem param;

    /* Import key into NSS. */
    key_item.type = siBuffer;
    key_item.data = (unsigned char *)key; /* const cast */
    key_item.len = keysize;
    slot = PK11_GetInternalSlot();
    symKey = PK11_ImportSymKey(slot, CKM_AES_GCM, PK11_OriginUnwrap,
                               CKA_ENCRYPT, &key_item, NULL);
    PK11_FreeSlot(slot);
    slot = NULL;
    if (!symKey) {
        fprintf(stderr, "PK11_ImportSymKey failed\n");
        goto loser;
    }

    gcm_params.pIv = (unsigned char *)iv; /* const cast */
    gcm_params.ulIvLen = ivsize;
    gcm_params.pAAD = (unsigned char *)aad; /* const cast */
    gcm_params.ulAADLen = aadlen;
    gcm_params.ulTagBits = tagsize * 8;

    param.type = siBuffer;
    param.data = (unsigned char *)&gcm_params;
    param.len = sizeof(gcm_params);

    if (PK11_Encrypt(symKey, CKM_AES_GCM, &param,
                     output, outputlen, maxoutputlen,
                     input, inputlen) != SECSuccess) {
        fprintf(stderr, "PK11_Encrypt failed\n");
        goto loser;
    }

    rv = SECSuccess;

loser:
    if (symKey != NULL) {
        PK11_FreeSymKey(symKey);
    }
    return rv;
}

static SECStatus
aes_decrypt_buf(
    const unsigned char *key, unsigned int keysize,
    const unsigned char *iv, unsigned int ivsize,
    unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
    const unsigned char *input, unsigned int inputlen,
    const unsigned char *aad, unsigned int aadlen,
    const unsigned char *tag, unsigned int tagsize)
{
    SECStatus rv = SECFailure;
    unsigned char concatenated[11 * 16]; /* 1 to 11 blocks */
    SECItem key_item;
    PK11SlotInfo *slot = NULL;
    PK11SymKey *symKey = NULL;
    CK_GCM_PARAMS gcm_params;
    SECItem param;

    if (inputlen + tagsize > sizeof(concatenated)) {
        fprintf(stderr, "aes_decrypt_buf: local buffer too small\n");
        goto loser;
    }
    memcpy(concatenated, input, inputlen);
    memcpy(concatenated + inputlen, tag, tagsize);

    /* Import key into NSS. */
    key_item.type = siBuffer;
    key_item.data = (unsigned char *)key; /* const cast */
    key_item.len = keysize;
    slot = PK11_GetInternalSlot();
    symKey = PK11_ImportSymKey(slot, CKM_AES_GCM, PK11_OriginUnwrap,
                               CKA_DECRYPT, &key_item, NULL);
    PK11_FreeSlot(slot);
    slot = NULL;
    if (!symKey) {
        fprintf(stderr, "PK11_ImportSymKey failed\n");
        goto loser;
    }

    gcm_params.pIv = (unsigned char *)iv;
    gcm_params.ulIvLen = ivsize;
    gcm_params.pAAD = (unsigned char *)aad;
    gcm_params.ulAADLen = aadlen;
    gcm_params.ulTagBits = tagsize * 8;

    param.type = siBuffer;
    param.data = (unsigned char *)&gcm_params;
    param.len = sizeof(gcm_params);

    if (PK11_Decrypt(symKey, CKM_AES_GCM, &param,
                     output, outputlen, maxoutputlen,
                     concatenated, inputlen + tagsize) != SECSuccess) {
        goto loser;
    }

    rv = SECSuccess;

loser:
    if (symKey != NULL) {
        PK11_FreeSymKey(symKey);
    }
    return rv;
}

/*
 * Perform the AES Known Answer Test (KAT) in Galois Counter Mode (GCM).
 *
 * respfn is the pathname of the RESPONSE file.
 */
static void
aes_gcm_kat(const char *respfn)
{
    char buf[512]; /* holds one line from the input REQUEST file.
                         * needs to be large enough to hold the longest
                         * line "CIPHERTEXT = <320 hex digits>\n".
                         */
    FILE *aesresp; /* input stream from the RESPONSE file */
    int i, j;
    unsigned int test_group = 0;
    unsigned int num_tests = 0;
    PRBool is_encrypt;
    unsigned char key[32]; /* 128, 192, or 256 bits */
    unsigned int keysize = 16;
    unsigned char iv[10 * 16]; /* 1 to 10 blocks */
    unsigned int ivsize = 12;
    unsigned char plaintext[10 * 16]; /* 1 to 10 blocks */
    unsigned int plaintextlen = 0;
    unsigned char aad[10 * 16]; /* 1 to 10 blocks */
    unsigned int aadlen = 0;
    unsigned char ciphertext[10 * 16]; /* 1 to 10 blocks */
    unsigned int ciphertextlen = 0;
    unsigned char tag[16];
    unsigned int tagsize = 16;
    unsigned char output[10 * 16]; /* 1 to 10 blocks */
    unsigned int outputlen = 0;

    unsigned int expected_keylen = 0;
    unsigned int expected_ivlen = 0;
    unsigned int expected_ptlen = 0;
    unsigned int expected_aadlen = 0;
    unsigned int expected_taglen = 0;
    SECStatus rv;

    if (strstr(respfn, "Encrypt") != NULL) {
        is_encrypt = PR_TRUE;
    } else if (strstr(respfn, "Decrypt") != NULL) {
        is_encrypt = PR_FALSE;
    } else {
        fprintf(stderr, "Input file name must contain Encrypt or Decrypt\n");
        exit(1);
    }
    aesresp = fopen(respfn, "r");
    if (aesresp == NULL) {
        fprintf(stderr, "Cannot open input file %s\n", respfn);
        exit(1);
    }
    while (fgets(buf, sizeof buf, aesresp) != NULL) {
        /* a comment or blank line */
        if (buf[0] == '#' || buf[0] == '\n') {
            continue;
        }
        /* [Keylen = ...], [IVlen = ...], etc. */
        if (buf[0] == '[') {
            if (strncmp(&buf[1], "Keylen = ", 9) == 0) {
                expected_keylen = atoi(&buf[10]);
            } else if (strncmp(&buf[1], "IVlen = ", 8) == 0) {
                expected_ivlen = atoi(&buf[9]);
            } else if (strncmp(&buf[1], "PTlen = ", 8) == 0) {
                expected_ptlen = atoi(&buf[9]);
            } else if (strncmp(&buf[1], "AADlen = ", 9) == 0) {
                expected_aadlen = atoi(&buf[10]);
            } else if (strncmp(&buf[1], "Taglen = ", 9) == 0) {
                expected_taglen = atoi(&buf[10]);

                test_group++;
                if (test_group > 1) {
                    /* Report num_tests for the previous test group. */
                    printf("%u tests\n", num_tests);
                }
                num_tests = 0;
                printf("Keylen = %u, IVlen = %u, PTlen = %u, AADlen = %u, "
                       "Taglen = %u: ",
                       expected_keylen, expected_ivlen,
                       expected_ptlen, expected_aadlen, expected_taglen);
                /* Convert lengths in bits to lengths in bytes. */
                PORT_Assert(expected_keylen % 8 == 0);
                expected_keylen /= 8;
                PORT_Assert(expected_ivlen % 8 == 0);
                expected_ivlen /= 8;
                PORT_Assert(expected_ptlen % 8 == 0);
                expected_ptlen /= 8;
                PORT_Assert(expected_aadlen % 8 == 0);
                expected_aadlen /= 8;
                PORT_Assert(expected_taglen % 8 == 0);
                expected_taglen /= 8;
            } else {
                fprintf(stderr, "Unexpected input line: %s\n", buf);
                exit(1);
            }
            continue;
        }
        /* "Count = x" begins a new data set */
        if (strncmp(buf, "Count", 5) == 0) {
            /* zeroize the variables for the test with this data set */
            memset(key, 0, sizeof key);
            keysize = 0;
            memset(iv, 0, sizeof iv);
            ivsize = 0;
            memset(plaintext, 0, sizeof plaintext);
            plaintextlen = 0;
            memset(aad, 0, sizeof aad);
            aadlen = 0;
            memset(ciphertext, 0, sizeof ciphertext);
            ciphertextlen = 0;
            memset(output, 0, sizeof output);
            outputlen = 0;
            num_tests++;
            continue;
        }
        /* Key = ... */
        if (strncmp(buf, "Key", 3) == 0) {
            i = 3;
            while (isspace(buf[i]) || buf[i] == '=') {
                i++;
            }
            for (j = 0; isxdigit(buf[i]); i += 2, j++) {
                hex_to_byteval(&buf[i], &key[j]);
            }
            keysize = j;
            if (keysize != expected_keylen) {
                fprintf(stderr, "Unexpected key length: %u vs. %u\n",
                        keysize, expected_keylen);
                exit(1);
            }
            continue;
        }
        /* IV = ... */
        if (strncmp(buf, "IV", 2) == 0) {
            i = 2;
            while (isspace(buf[i]) || buf[i] == '=') {
                i++;
            }
            for (j = 0; isxdigit(buf[i]); i += 2, j++) {
                hex_to_byteval(&buf[i], &iv[j]);
            }
            ivsize = j;
            if (ivsize != expected_ivlen) {
                fprintf(stderr, "Unexpected IV length: %u vs. %u\n",
                        ivsize, expected_ivlen);
                exit(1);
            }
            continue;
        }
        /* PT = ... */
        if (strncmp(buf, "PT", 2) == 0) {
            i = 2;
            while (isspace(buf[i]) || buf[i] == '=') {
                i++;
            }
            for (j = 0; isxdigit(buf[i]); i += 2, j++) {
                hex_to_byteval(&buf[i], &plaintext[j]);
            }
            plaintextlen = j;
            if (plaintextlen != expected_ptlen) {
                fprintf(stderr, "Unexpected PT length: %u vs. %u\n",
                        plaintextlen, expected_ptlen);
                exit(1);
            }

            if (!is_encrypt) {
                rv = aes_decrypt_buf(key, keysize, iv, ivsize,
                                     output, &outputlen, sizeof output,
                                     ciphertext, ciphertextlen, aad, aadlen, tag, tagsize);
                if (rv != SECSuccess) {
                    fprintf(stderr, "aes_decrypt_buf failed\n");
                    goto loser;
                }
                if (outputlen != plaintextlen) {
                    fprintf(stderr, "aes_decrypt_buf: wrong output size\n");
                    goto loser;
                }
                if (memcmp(output, plaintext, plaintextlen) != 0) {
                    fprintf(stderr, "aes_decrypt_buf: wrong plaintext\n");
                    goto loser;
                }
            }
            continue;
        }
        /* FAIL */
        if (strncmp(buf, "FAIL", 4) == 0) {
            plaintextlen = 0;

            PORT_Assert(!is_encrypt);
            rv = aes_decrypt_buf(key, keysize, iv, ivsize,
                                 output, &outputlen, sizeof output,
                                 ciphertext, ciphertextlen, aad, aadlen, tag, tagsize);
            if (rv != SECFailure) {
                fprintf(stderr, "aes_decrypt_buf succeeded unexpectedly\n");
                goto loser;
            }
            if (PORT_GetError() != SEC_ERROR_BAD_DATA) {
                fprintf(stderr, "aes_decrypt_buf failed with incorrect "
                                "error code\n");
                goto loser;
            }
            continue;
        }
        /* AAD = ... */
        if (strncmp(buf, "AAD", 3) == 0) {
            i = 3;
            while (isspace(buf[i]) || buf[i] == '=') {
                i++;
            }
            for (j = 0; isxdigit(buf[i]); i += 2, j++) {
                hex_to_byteval(&buf[i], &aad[j]);
            }
            aadlen = j;
            if (aadlen != expected_aadlen) {
                fprintf(stderr, "Unexpected AAD length: %u vs. %u\n",
                        aadlen, expected_aadlen);
                exit(1);
            }
            continue;
        }
        /* CT = ... */
        if (strncmp(buf, "CT", 2) == 0) {
            i = 2;
            while (isspace(buf[i]) || buf[i] == '=') {
                i++;
            }
            for (j = 0; isxdigit(buf[i]); i += 2, j++) {
                hex_to_byteval(&buf[i], &ciphertext[j]);
            }
            ciphertextlen = j;
            if (ciphertextlen != expected_ptlen) {
                fprintf(stderr, "Unexpected CT length: %u vs. %u\n",
                        ciphertextlen, expected_ptlen);
                exit(1);
            }
            continue;
        }
        /* Tag = ... */
        if (strncmp(buf, "Tag", 3) == 0) {
            i = 3;
            while (isspace(buf[i]) || buf[i] == '=') {
                i++;
            }
            for (j = 0; isxdigit(buf[i]); i += 2, j++) {
                hex_to_byteval(&buf[i], &tag[j]);
            }
            tagsize = j;
            if (tagsize != expected_taglen) {
                fprintf(stderr, "Unexpected tag length: %u vs. %u\n",
                        tagsize, expected_taglen);
                exit(1);
            }

            if (is_encrypt) {
                rv = aes_encrypt_buf(key, keysize, iv, ivsize,
                                     output, &outputlen, sizeof output,
                                     plaintext, plaintextlen, aad, aadlen, tagsize);
                if (rv != SECSuccess) {
                    fprintf(stderr, "aes_encrypt_buf failed\n");
                    goto loser;
                }
                if (outputlen != plaintextlen + tagsize) {
                    fprintf(stderr, "aes_encrypt_buf: wrong output size\n");
                    goto loser;
                }
                if (memcmp(output, ciphertext, plaintextlen) != 0) {
                    fprintf(stderr, "aes_encrypt_buf: wrong ciphertext\n");
                    goto loser;
                }
                if (memcmp(output + plaintextlen, tag, tagsize) != 0) {
                    fprintf(stderr, "aes_encrypt_buf: wrong tag\n");
                    goto loser;
                }
            }
            continue;
        }
    }
    /* Report num_tests for the last test group. */
    printf("%u tests\n", num_tests);
    printf("%u test groups\n", test_group);
    printf("PASS\n");
loser:
    fclose(aesresp);
}

int
main(int argc, char **argv)
{
    if (argc < 2)
        exit(1);

    NSS_NoDB_Init(NULL);

    /*************/
    /*   AES     */
    /*************/
    if (strcmp(argv[1], "aes") == 0) {
        /* argv[2]=kat argv[3]=gcm argv[4]=<test name>.rsp */
        if (strcmp(argv[2], "kat") == 0) {
            /* Known Answer Test (KAT) */
            aes_gcm_kat(argv[4]);
        }
    }

    NSS_Shutdown();
    return 0;
}
