/* 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 "sechash.h"
#include "secoidt.h"
#include "secerr.h"
#include "blapi.h"
#include "pk11func.h" /* for the PK11_ calls below. */

static void *
null_hash_new_context(void)
{
    return NULL;
}

static void *
null_hash_clone_context(void *v)
{
    PORT_Assert(v == NULL);
    return NULL;
}

static void
null_hash_begin(void *v)
{
}

static void
null_hash_update(void *v, const unsigned char *input, unsigned int length)
{
}

static void
null_hash_end(void *v, unsigned char *output, unsigned int *outLen,
              unsigned int maxOut)
{
    *outLen = 0;
}

static void
null_hash_destroy_context(void *v, PRBool b)
{
    PORT_Assert(v == NULL);
}

static void *
md2_NewContext(void)
{
    return (void *)PK11_CreateDigestContext(SEC_OID_MD2);
}

static void *
md5_NewContext(void)
{
    return (void *)PK11_CreateDigestContext(SEC_OID_MD5);
}

static void *
sha1_NewContext(void)
{
    return (void *)PK11_CreateDigestContext(SEC_OID_SHA1);
}

static void *
sha224_NewContext(void)
{
    return (void *)PK11_CreateDigestContext(SEC_OID_SHA224);
}

static void *
sha256_NewContext(void)
{
    return (void *)PK11_CreateDigestContext(SEC_OID_SHA256);
}

static void *
sha384_NewContext(void)
{
    return (void *)PK11_CreateDigestContext(SEC_OID_SHA384);
}

static void *
sha512_NewContext(void)
{
    return (void *)PK11_CreateDigestContext(SEC_OID_SHA512);
}

const SECHashObject SECHashObjects[] = {
    { 0,
      (void *(*)(void))null_hash_new_context,
      (void *(*)(void *))null_hash_clone_context,
      (void (*)(void *, PRBool))null_hash_destroy_context,
      (void (*)(void *))null_hash_begin,
      (void (*)(void *, const unsigned char *, unsigned int))null_hash_update,
      (void (*)(void *, unsigned char *, unsigned int *,
                unsigned int))null_hash_end,
      0,
      HASH_AlgNULL },
    { MD2_LENGTH,
      (void *(*)(void))md2_NewContext,
      (void *(*)(void *))PK11_CloneContext,
      (void (*)(void *, PRBool))PK11_DestroyContext,
      (void (*)(void *))PK11_DigestBegin,
      (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp,
      (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
          PK11_DigestFinal,
      MD2_BLOCK_LENGTH,
      HASH_AlgMD2 },
    { MD5_LENGTH,
      (void *(*)(void))md5_NewContext,
      (void *(*)(void *))PK11_CloneContext,
      (void (*)(void *, PRBool))PK11_DestroyContext,
      (void (*)(void *))PK11_DigestBegin,
      (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp,
      (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
          PK11_DigestFinal,
      MD5_BLOCK_LENGTH,
      HASH_AlgMD5 },
    { SHA1_LENGTH,
      (void *(*)(void))sha1_NewContext,
      (void *(*)(void *))PK11_CloneContext,
      (void (*)(void *, PRBool))PK11_DestroyContext,
      (void (*)(void *))PK11_DigestBegin,
      (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp,
      (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
          PK11_DigestFinal,
      SHA1_BLOCK_LENGTH,
      HASH_AlgSHA1 },
    { SHA256_LENGTH,
      (void *(*)(void))sha256_NewContext,
      (void *(*)(void *))PK11_CloneContext,
      (void (*)(void *, PRBool))PK11_DestroyContext,
      (void (*)(void *))PK11_DigestBegin,
      (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp,
      (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
          PK11_DigestFinal,
      SHA256_BLOCK_LENGTH,
      HASH_AlgSHA256 },
    { SHA384_LENGTH,
      (void *(*)(void))sha384_NewContext,
      (void *(*)(void *))PK11_CloneContext,
      (void (*)(void *, PRBool))PK11_DestroyContext,
      (void (*)(void *))PK11_DigestBegin,
      (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp,
      (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
          PK11_DigestFinal,
      SHA384_BLOCK_LENGTH,
      HASH_AlgSHA384 },
    { SHA512_LENGTH,
      (void *(*)(void))sha512_NewContext,
      (void *(*)(void *))PK11_CloneContext,
      (void (*)(void *, PRBool))PK11_DestroyContext,
      (void (*)(void *))PK11_DigestBegin,
      (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp,
      (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
          PK11_DigestFinal,
      SHA512_BLOCK_LENGTH,
      HASH_AlgSHA512 },
    { SHA224_LENGTH,
      (void *(*)(void))sha224_NewContext,
      (void *(*)(void *))PK11_CloneContext,
      (void (*)(void *, PRBool))PK11_DestroyContext,
      (void (*)(void *))PK11_DigestBegin,
      (void (*)(void *, const unsigned char *, unsigned int))PK11_DigestOp,
      (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
          PK11_DigestFinal,
      SHA224_BLOCK_LENGTH,
      HASH_AlgSHA224 },
};

const SECHashObject *
HASH_GetHashObject(HASH_HashType type)
{
    return &SECHashObjects[type];
}

HASH_HashType
HASH_GetHashTypeByOidTag(SECOidTag hashOid)
{
    HASH_HashType ht = HASH_AlgNULL;

    switch (hashOid) {
        case SEC_OID_MD2:
            ht = HASH_AlgMD2;
            break;
        case SEC_OID_MD5:
            ht = HASH_AlgMD5;
            break;
        case SEC_OID_SHA1:
            ht = HASH_AlgSHA1;
            break;
        case SEC_OID_SHA224:
            ht = HASH_AlgSHA224;
            break;
        case SEC_OID_SHA256:
            ht = HASH_AlgSHA256;
            break;
        case SEC_OID_SHA384:
            ht = HASH_AlgSHA384;
            break;
        case SEC_OID_SHA512:
            ht = HASH_AlgSHA512;
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
            break;
    }
    return ht;
}

SECOidTag
HASH_GetHashOidTagByHashType(HASH_HashType type)
{
    SECOidTag oid = SEC_OID_UNKNOWN;

    switch (type) {
        case HASH_AlgMD2:
            oid = SEC_OID_MD2;
            break;
        case HASH_AlgMD5:
            oid = SEC_OID_MD5;
            break;
        case HASH_AlgSHA1:
            oid = SEC_OID_SHA1;
            break;
        case HASH_AlgSHA224:
            oid = SEC_OID_SHA224;
            break;
        case HASH_AlgSHA256:
            oid = SEC_OID_SHA256;
            break;
        case HASH_AlgSHA384:
            oid = SEC_OID_SHA384;
            break;
        case HASH_AlgSHA512:
            oid = SEC_OID_SHA512;
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
            break;
    }
    return oid;
}

SECOidTag
HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid)
{
    SECOidTag hashOid = SEC_OID_UNKNOWN;

    switch (hmacOid) {
        /* no oid exists for HMAC_MD2 */
        /* NSS does not define a oid for HMAC_MD4 */
        case SEC_OID_HMAC_SHA1:
            hashOid = SEC_OID_SHA1;
            break;
        case SEC_OID_HMAC_SHA224:
            hashOid = SEC_OID_SHA224;
            break;
        case SEC_OID_HMAC_SHA256:
            hashOid = SEC_OID_SHA256;
            break;
        case SEC_OID_HMAC_SHA384:
            hashOid = SEC_OID_SHA384;
            break;
        case SEC_OID_HMAC_SHA512:
            hashOid = SEC_OID_SHA512;
            break;
        default:
            hashOid = SEC_OID_UNKNOWN;
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
            break;
    }
    return hashOid;
}

SECOidTag
HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid)
{
    SECOidTag hmacOid = SEC_OID_UNKNOWN;

    switch (hashOid) {
        /* no oid exists for HMAC_MD2 */
        /* NSS does not define a oid for HMAC_MD4 */
        case SEC_OID_SHA1:
            hmacOid = SEC_OID_HMAC_SHA1;
            break;
        case SEC_OID_SHA224:
            hmacOid = SEC_OID_HMAC_SHA224;
            break;
        case SEC_OID_SHA256:
            hmacOid = SEC_OID_HMAC_SHA256;
            break;
        case SEC_OID_SHA384:
            hmacOid = SEC_OID_HMAC_SHA384;
            break;
        case SEC_OID_SHA512:
            hmacOid = SEC_OID_HMAC_SHA512;
            break;
        default:
            hmacOid = SEC_OID_UNKNOWN;
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
            break;
    }
    return hmacOid;
}

const SECHashObject *
HASH_GetHashObjectByOidTag(SECOidTag hashOid)
{
    HASH_HashType ht = HASH_GetHashTypeByOidTag(hashOid);

    return (ht == HASH_AlgNULL) ? NULL : &SECHashObjects[ht];
}

/* returns zero for unknown hash OID */
unsigned int
HASH_ResultLenByOidTag(SECOidTag hashOid)
{
    const SECHashObject *hashObject = HASH_GetHashObjectByOidTag(hashOid);
    unsigned int resultLen = 0;

    if (hashObject)
        resultLen = hashObject->length;
    return resultLen;
}

/* returns zero if hash type invalid. */
unsigned int
HASH_ResultLen(HASH_HashType type)
{
    if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        return (0);
    }

    return (SECHashObjects[type].length);
}

unsigned int
HASH_ResultLenContext(HASHContext *context)
{
    return (context->hashobj->length);
}

SECStatus
HASH_HashBuf(HASH_HashType type,
             unsigned char *dest,
             const unsigned char *src,
             PRUint32 src_len)
{
    HASHContext *cx;
    unsigned int part;

    if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) {
        return (SECFailure);
    }

    cx = HASH_Create(type);
    if (cx == NULL) {
        return (SECFailure);
    }
    HASH_Begin(cx);
    HASH_Update(cx, src, src_len);
    HASH_End(cx, dest, &part, HASH_ResultLenContext(cx));
    HASH_Destroy(cx);

    return (SECSuccess);
}

HASHContext *
HASH_Create(HASH_HashType type)
{
    void *hash_context = NULL;
    HASHContext *ret = NULL;

    if ((type < HASH_AlgNULL) || (type >= HASH_AlgTOTAL)) {
        return (NULL);
    }

    hash_context = (*SECHashObjects[type].create)();
    if (hash_context == NULL) {
        goto loser;
    }

    ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
    if (ret == NULL) {
        goto loser;
    }

    ret->hash_context = hash_context;
    ret->hashobj = &SECHashObjects[type];

    return (ret);

loser:
    if (hash_context != NULL) {
        (*SECHashObjects[type].destroy)(hash_context, PR_TRUE);
    }

    return (NULL);
}

HASHContext *
HASH_Clone(HASHContext *context)
{
    void *hash_context = NULL;
    HASHContext *ret = NULL;

    hash_context = (*context->hashobj->clone)(context->hash_context);
    if (hash_context == NULL) {
        goto loser;
    }

    ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
    if (ret == NULL) {
        goto loser;
    }

    ret->hash_context = hash_context;
    ret->hashobj = context->hashobj;

    return (ret);

loser:
    if (hash_context != NULL) {
        (*context->hashobj->destroy)(hash_context, PR_TRUE);
    }

    return (NULL);
}

void
HASH_Destroy(HASHContext *context)
{
    (*context->hashobj->destroy)(context->hash_context, PR_TRUE);
    PORT_Free(context);
    return;
}

void
HASH_Begin(HASHContext *context)
{
    (*context->hashobj->begin)(context->hash_context);
    return;
}

void
HASH_Update(HASHContext *context,
            const unsigned char *src,
            unsigned int len)
{
    (*context->hashobj->update)(context->hash_context, src, len);
    return;
}

void
HASH_End(HASHContext *context,
         unsigned char *result,
         unsigned int *result_len,
         unsigned int max_result_len)
{
    (*context->hashobj->end)(context->hash_context, result, result_len,
                             max_result_len);
    return;
}

HASH_HashType
HASH_GetType(HASHContext *context)
{
    return (context->hashobj->type);
}
