Commit 0a2ab7ff authored by Robert Dubner's avatar Robert Dubner
Browse files

Update HMACMD5 with updated IPR and formatting

parent 388d5af8
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2021 The OpenLDAP Foundation.
* Portions Copyright 2021 Robert Dubner, Symas Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -11,31 +10,36 @@
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
*
* As noted below, portions of this code were derived from public-domain sources
*
*/
#include "radiusov.h"
#include <string.h>
#include "hmacmd5.h"
// Calculate HMAC per RFC2104 https://datatracker.ietf.org/doc/html/rfc2104
// Note: This code was modified from a copy of the Sample Code in the
// Appendix of RFC2104. In particular, the sample code describes an
// routine that hashes a contiguous block of memory; the modifications
// here provide initialize/update/finalize functions
void
hmac_md5(uint8_t digest[MD5_DIGEST_LENGTH],
uint8_t const *text,
size_t text_len,
uint8_t const *key,
size_t key_len)
hmac_md5( uint8_t digest[MD5_DIGEST_LENGTH],
uint8_t const *text,
size_t text_len,
uint8_t const *key,
size_t key_len)
{
// This entry point calculates HMAC-MD5 on a contiguous block of data
MD5_CTX context;
hmac_md5_init( &context, key, key_len);
HMAC_MD5_CTX context;
hmac_md5_init(&context, key, key_len);
hmac_md5_update(&context, text, text_len);
hmac_md5_final( &context, digest);
hmac_md5_final(&context,digest);
}
/* The following entry points allow for building a HMAC-MD5 in pieces, rather than
in a single contiguous block */
void
hmac_md5_init(MD5_CTX *context,
hmac_md5_init(HMAC_MD5_CTX *context,
uint8_t const *key,
size_t key_len)
{
......@@ -49,20 +53,20 @@ hmac_md5_init(MD5_CTX *context,
md5_update(&tctx, key, key_len);
md5_final(tk, &tctx);
memcpy(context->key, tk, 16);
bcopy(tk, context->key, 16);
key_len = 16;
}
else
{
// Key is <= 64 bytes, so just copy it over.
memcpy(context->key, key, key_len);
bcopy(key, context->key, key_len);
context->key_len = key_len;
}
/* start out by storing key in pads */
uint8_t k_ipad[64]; /* inner padding - key XORd with ipad */
memset( k_ipad, 0, sizeof(k_ipad));
memcpy( k_ipad, &context->key, context->key_len);
uint8_t k_ipad[64]; /* inner padding - key XORd with ipad */
bzero( k_ipad, sizeof(k_ipad));
bcopy( &context->key, k_ipad, context->key_len);
/* XOR key with ipad and opad values */
for (int i = 0; i < 64; i++)
......@@ -72,28 +76,28 @@ hmac_md5_init(MD5_CTX *context,
/*
* perform inner MD5
*/
md5_init(context); // init context for first pass
md5_update(context, k_ipad, 64); // start with inner pad */
md5_init(&context->context); // init context for first pass
md5_update(&context->context, k_ipad, 64); // start with inner pad */
// We are now ready for any number of hmac_md5_update() calls
}
void
hmac_md5_update( MD5_CTX *context,
hmac_md5_update( HMAC_MD5_CTX *context,
uint8_t const *text,
size_t text_len)
{
md5_update(context, text, text_len); // start with inner pad */
md5_update(&context->context, text, text_len); // start with inner pad */
// After those are all done, call hmac_md5_update()
}
void
hmac_md5_final( MD5_CTX *context,
hmac_md5_final( HMAC_MD5_CTX *context,
uint8_t *digest)
{
uint8_t k_opad[64]; /* outer padding - key XORd with opad */
memset( k_opad, 0, sizeof(k_opad));
memcpy( k_opad, context->key, context->key_len);
uint8_t k_opad[64]; /* outer padding - key XORd with opad */
bzero( k_opad, sizeof(k_opad));
bcopy( context->key, k_opad, context->key_len);
/* XOR key with ipad and opad values */
for (int i = 0; i < 64; i++)
......@@ -102,13 +106,13 @@ hmac_md5_final( MD5_CTX *context,
}
// Finish up the first pass
md5_final(digest, context);
md5_final(digest, &context->context);
/*
* perform outer MD5
* perform outer MD5, re-using the MD5 context
*/
md5_init(context); // init context for second pass
md5_update(context, k_opad, 64); // start with outer pad
md5_update(context, digest, 16); // then results of first hash
md5_final(digest, context); // finish up second pass
md5_init(&context->context); // init context for second pass
md5_update(&context->context, k_opad, 64); // start with outer pad
md5_update(&context->context, digest, 16); // then results of first hash
md5_final(digest, &context->context); // finish up second pass
}
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2021 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*
* As noted below, portions of this code were derived from public-domain sources
*
*/
#ifndef _h_HMACMD5_H
#define _h_HMACMD5_H
#include <stdint.h>
#include "md5.h"
typedef struct HMAC_MD5_CTX_
{
uint8_t key[64];
size_t key_len;
MD5_CTX context;
} HMAC_MD5_CTX;
void hmac_md5( uint8_t digest[MD5_DIGEST_LENGTH],
uint8_t const *text,
size_t text_len,
uint8_t const *key,
size_t key_len);
void hmac_md5_init( HMAC_MD5_CTX *context,
uint8_t const *key,
size_t key_len);
void hmac_md5_update(HMAC_MD5_CTX *context,
uint8_t const *text,
size_t text_len);
void hmac_md5_final( HMAC_MD5_CTX *context,
uint8_t *digest);
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment