9eb24f1f84885d5c2e51a7f675264db398c31af7Tinderbox User * Copyright (C) 2000, 2001, 2004-2007, 2009, 2013-2018 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
53f0234c3e3a845245042affb1f20a189d8791b9Automatic Updater/* $Id: hmacmd5.c,v 1.16 2009/02/06 23:47:42 tbox Exp $ */
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington * This code implements the HMAC-MD5 keyed hash algorithm
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * described in RFC2104.
22bed621ef87bc8b6c1fea599b02c4b38dd6bf48Mark Andrews#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
76af83c9adb772f7b045c62cf8b411165bfaa5efMark Andrews#define HMAC_CTX_new() &(ctx->_ctx), HMAC_CTX_init(&(ctx->_ctx))
76af83c9adb772f7b045c62cf8b411165bfaa5efMark Andrews#define HMAC_CTX_free(ptr) HMAC_CTX_cleanup(ptr)
c1d7e0562f6a72ecc07ab5140cf2b88183adbd08Francis Dupontisc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
c1d7e0562f6a72ecc07ab5140cf2b88183adbd08Francis Dupont unsigned int len)
76af83c9adb772f7b045c62cf8b411165bfaa5efMark Andrews RUNTIME_CHECK(HMAC_Init_ex(ctx->ctx, (const void *) key,
c1d7e0562f6a72ecc07ab5140cf2b88183adbd08Francis Dupontisc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
c1d7e0562f6a72ecc07ab5140cf2b88183adbd08Francis Dupont unsigned int len)
76af83c9adb772f7b045c62cf8b411165bfaa5efMark Andrews RUNTIME_CHECK(HMAC_Update(ctx->ctx, buf, (int) len) == 1);
c1d7e0562f6a72ecc07ab5140cf2b88183adbd08Francis Dupontisc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
76af83c9adb772f7b045c62cf8b411165bfaa5efMark Andrews RUNTIME_CHECK(HMAC_Final(ctx->ctx, digest, NULL) == 1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int len)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
78608b0a454246d0e1e0169f1d671b8427e48199Francis Dupont keyTemplate[5].ulValueLen = ISC_MD5_DIGESTLENGTH;
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_SignFinal(ctx->session, garbage, &len);
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(garbage, sizeof(garbage));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int len)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (void) pkcs_C_DestroyObject(ctx->session, ctx->object);
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews/* Replace missing CKM_MD5_HMAC PKCS#11 mechanism */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int len)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt RUNTIME_CHECK((ctx->key = pk11_mem_get(PADLEN)) != NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < PADLEN; i++)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int len)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntisc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < PADLEN; i++)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech));
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington * Start HMAC-MD5 process. Initialize an md5 context and digest the key.
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellingtonisc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington unsigned int len)
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington for (i = 0; i < PADLEN; i++)
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington isc_md5_update(&ctx->md5ctx, ipad, sizeof(ipad));
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellingtonisc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
b5252fcde512405a68dd4becfe683d9763bd0feaMukund Sivaraman isc_safe_memwipe(ctx->key, sizeof(ctx->key));
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington * Update context to reflect the concatenation of another buffer full
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellingtonisc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington unsigned int len)
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington * Compute signature - finalize MD5 operation and reapply MD5.
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellingtonisc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington for (i = 0; i < PADLEN; i++)
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington isc_md5_update(&ctx->md5ctx, opad, sizeof(opad));
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington isc_md5_update(&ctx->md5ctx, digest, ISC_MD5_DIGESTLENGTH);
c1d7e0562f6a72ecc07ab5140cf2b88183adbd08Francis Dupont#endif /* !ISC_PLATFORM_OPENSSLHASH */
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington * Verify signature - finalize MD5 operation and reapply MD5, then
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington * compare to the supplied digest.
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellingtonisc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest) {
c6d4f781529d2f28693546b25b2967d44ec89e60Mark Andrews return (isc_hmacmd5_verify2(ctx, digest, ISC_MD5_DIGESTLENGTH));
c6d4f781529d2f28693546b25b2967d44ec89e60Mark Andrewsisc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) {
9c4cba349f52bb8176c3858b2b5b340f13603802Brian Wellington unsigned char newdigest[ISC_MD5_DIGESTLENGTH];
420a43c8d8028992a4e9c170022f97bfac689025Evan Hunt return (isc_safe_memequal(digest, newdigest, len));
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont * Check for MD5 support; if it does not work, raise a fatal error.
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont * Use the first test vector from RFC 2104, with a second round using
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont * a too-short key.
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont * Standard use is testing 0 and expecting result true.
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont * Testing use is testing 1..4 and expecting result false.
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont unsigned char key[] = { /* 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b */
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont 0xad, 0xb8, 0x48, 0x05, 0xb8, 0x8d, 0x03, 0xe5,
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont 0x90, 0x1e, 0x4b, 0x05, 0x69, 0xce, 0x35, 0xea
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont * Introduce a fault for testing.
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont * These functions do not return anything; any failure will be fatal.
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont result = isc_hmacmd5_verify2(&ctx, expected, sizeof(expected));
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont /* Second round using a byte key */
f9c410d93711fbf312a0162f1e2d3f2a5ede69afFrancis Dupont return (isc_hmacmd5_verify2(&ctx, expected2, sizeof(expected2)));
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#else /* !PK11_MD5_DISABLE */
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews/* Make the Visual Studio linker happy */
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#endif /* PK11_MD5_DISABLE */