summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/cryptohi/sechash.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/cryptohi/sechash.c')
-rw-r--r--security/nss/lib/cryptohi/sechash.c471
1 files changed, 471 insertions, 0 deletions
diff --git a/security/nss/lib/cryptohi/sechash.c b/security/nss/lib/cryptohi/sechash.c
new file mode 100644
index 0000000000..474fdfff9e
--- /dev/null
+++ b/security/nss/lib/cryptohi/sechash.c
@@ -0,0 +1,471 @@
+/* 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);
+}