/*
 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 *
 * Alternatively, you may distribute this code in source or binary
 * form, with or without modification, provided that the following
 * conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the above disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the above
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

/** @file
 *
 * Hash-based derivation function (Hash_df)
 *
 * This algorithm is designed to comply with ANS X9.82 Part 3-2007
 * Section 10.5.2.  This standard is not freely available, but most of
 * the text appears to be shared with NIST SP 800-90, which can be
 * downloaded from
 *
 *     http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
 *
 * Where possible, references are given to both documents.  In the
 * case of any disagreement, ANS X9.82 takes priority over NIST SP
 * 800-90.  (In particular, note that some algorithms that are
 * Approved by NIST SP 800-90 are not Approved by ANS X9.82.)
 */

#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/crypto.h>
#include <ipxe/hash_df.h>

/**
 * Distribute entropy throughout a buffer
 *
 * @v hash		Underlying hash algorithm
 * @v input		Input data
 * @v input_len		Length of input data, in bytes
 * @v output		Output buffer
 * @v output_len	Length of output buffer, in bytes
 *
 * This is the Hash_df function defined in ANS X9.82 Part 3-2007
 * Section 10.5.2 (NIST SP 800-90 Section 10.4.1).
 *
 * The number of bits requested is implicit in the length of the
 * output buffer.  Requests must be for an integral number of bytes.
 *
 * The output buffer is filled incrementally with each iteration of
 * the central loop, rather than constructing an overall "temp" and
 * then taking the leftmost(no_of_bits_to_return) bits.
 *
 * There is no way for the Hash_df function to fail.  The returned
 * status SUCCESS is implicit.
 */
void hash_df ( struct digest_algorithm *hash, const void *input,
	       size_t input_len, void *output, size_t output_len ) {
	uint8_t context[hash->ctxsize];
	uint8_t digest[hash->digestsize];
	size_t frag_len;
	struct {
		uint8_t pad[3];
		uint8_t counter;
		uint32_t no_of_bits_to_return;
	} __attribute__ (( packed )) prefix;
	void *temp;
	size_t remaining;

	DBGC ( &hash_df, "HASH_DF input:\n" );
	DBGC_HDA ( &hash_df, 0, input, input_len );

	/* Sanity checks */
	assert ( input != NULL );
	assert ( output != NULL );

	/* 1.  temp = the Null string
	 * 2.  len = ceil ( no_of_bits_to_return / outlen )
	 *
	 * (Nothing to do.  We fill the output buffer incrementally,
	 * rather than constructing the complete "temp" in-memory.
	 * "len" is implicit in the number of iterations required to
	 * fill the output buffer, and so is not calculated
	 * explicitly.)
	 */

	/* 3.  counter = an 8-bit binary value representing the integer "1" */
	prefix.counter = 1;

	/* 4.  For i = 1 to len do */
	for ( temp = output, remaining = output_len ; remaining > 0 ; ) {

		/* Comment: in step 5.1 (sic), no_of_bits_to_return is
		 * used as a 32-bit string.
		 *
		 * 4.1  temp = temp || Hash ( counter || no_of_bits_to_return
		 *                            || input_string )
		 */
		prefix.no_of_bits_to_return = htonl ( output_len * 8 );
		digest_init ( hash, context );
		digest_update ( hash, context, &prefix.counter,
				( sizeof ( prefix ) -
				  offsetof ( typeof ( prefix ), counter ) ) );
		digest_update ( hash, context, input, input_len );
		digest_final ( hash, context, digest );

		/* 4.2  counter = counter + 1 */
		prefix.counter++;

		/* 5.    requested_bits = Leftmost ( no_of_bits_to_return )
		 *       of temp
		 *
		 * (We fill the output buffer incrementally.)
		 */
		frag_len = sizeof ( digest );
		if ( frag_len > remaining )
			frag_len = remaining;
		memcpy ( temp, digest, frag_len );
		temp += frag_len;
		remaining -= frag_len;
	}

	/* 6.  Return SUCCESS and requested_bits */
	DBGC ( &hash_df, "HASH_DF output:\n" );
	DBGC_HDA ( &hash_df, 0, output, output_len );
	return;
}
