/*
 * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <gpxe/crypto.h>
#include <gpxe/sha1.h>
#include <gpxe/hmac.h>
#include <stdint.h>
#include <byteswap.h>

/**
 * SHA1 pseudorandom function for creating derived keys
 *
 * @v key	Master key with which this call is associated
 * @v key_len	Length of key
 * @v label	NUL-terminated ASCII string describing purpose of PRF data
 * @v data	Further data that should be included in the PRF
 * @v data_len	Length of further PRF data
 * @v prf_len	Bytes of PRF to generate
 * @ret prf	Pseudorandom function bytes
 *
 * This is the PRF variant used by 802.11, defined in IEEE 802.11-2007
 * 8.5.5.1. EAP-FAST uses a different SHA1-based PRF, and TLS uses an
 * MD5-based PRF.
 */
void prf_sha1 ( const void *key, size_t key_len, const char *label,
		const void *data, size_t data_len, void *prf, size_t prf_len )
{
	u32 blk;
	u8 keym[key_len];	/* modifiable copy of key */
	u8 in[strlen ( label ) + 1 + data_len + 1]; /* message to HMAC */
	u8 *in_blknr;		/* pointer to last byte of in, block number */
	u8 out[SHA1_SIZE];	/* HMAC-SHA1 result */
	u8 sha1_ctx[SHA1_CTX_SIZE]; /* SHA1 context */
	const size_t label_len = strlen ( label );

	/* The HMAC-SHA-1 is calculated using the given key on the
	   message text `label', followed by a NUL, followed by one
	   byte indicating the block number (0 for first). */

	memcpy ( keym, key, key_len );

	memcpy ( in, label, strlen ( label ) + 1 );
	memcpy ( in + label_len + 1, data, data_len );
	in_blknr = in + label_len + 1 + data_len;

	for ( blk = 0 ;; blk++ ) {
		*in_blknr = blk;

		hmac_init ( &sha1_algorithm, sha1_ctx, keym, &key_len );
		hmac_update ( &sha1_algorithm, sha1_ctx, in, sizeof ( in ) );
		hmac_final ( &sha1_algorithm, sha1_ctx, keym, &key_len, out );

		if ( prf_len <= SHA1_SIZE ) {
			memcpy ( prf, out, prf_len );
			break;
		}

		memcpy ( prf, out, SHA1_SIZE );
		prf_len -= SHA1_SIZE;
		prf += SHA1_SIZE;
	}
}

/**
 * PBKDF2 key derivation function inner block operation
 *
 * @v passphrase	Passphrase from which to derive key
 * @v pass_len		Length of passphrase
 * @v salt		Salt to include in key
 * @v salt_len		Length of salt
 * @v iterations	Number of iterations of SHA1 to perform
 * @v blocknr		Index of this block, starting at 1
 * @ret block		SHA1_SIZE bytes of PBKDF2 data
 *
 * The operation of this function is described in RFC 2898.
 */
static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
			    const void *salt, size_t salt_len,
			    int iterations, u32 blocknr, u8 *block )
{
	u8 pass[pass_len];	/* modifiable passphrase */
	u8 in[salt_len + 4];	/* input buffer to first round */
	u8 last[SHA1_SIZE];	/* output of round N, input of N+1 */
	u8 sha1_ctx[SHA1_CTX_SIZE];
	u8 *next_in = in;	/* changed to `last' after first round */
	int next_size = sizeof ( in );
	int i, j;

	blocknr = htonl ( blocknr );

	memcpy ( pass, passphrase, pass_len );
	memcpy ( in, salt, salt_len );
	memcpy ( in + salt_len, &blocknr, 4 );
	memset ( block, 0, SHA1_SIZE );

	for ( i = 0; i < iterations; i++ ) {
		hmac_init ( &sha1_algorithm, sha1_ctx, pass, &pass_len );
		hmac_update ( &sha1_algorithm, sha1_ctx, next_in, next_size );
		hmac_final ( &sha1_algorithm, sha1_ctx, pass, &pass_len, last );

		for ( j = 0; j < SHA1_SIZE; j++ ) {
			block[j] ^= last[j];
		}

		next_in = last;
		next_size = SHA1_SIZE;
	}
}

/**
 * PBKDF2 key derivation function using SHA1
 *
 * @v passphrase	Passphrase from which to derive key
 * @v pass_len		Length of passphrase
 * @v salt		Salt to include in key
 * @v salt_len		Length of salt
 * @v iterations	Number of iterations of SHA1 to perform
 * @v key_len		Length of key to generate
 * @ret key		Generated key bytes
 *
 * This is used most notably in 802.11 WPA passphrase hashing, in
 * which case the salt is the SSID, 4096 iterations are used, and a
 * 32-byte key is generated that serves as the Pairwise Master Key for
 * EAPOL authentication.
 *
 * The operation of this function is further described in RFC 2898.
 */
void pbkdf2_sha1 ( const void *passphrase, size_t pass_len,
		   const void *salt, size_t salt_len,
		   int iterations, void *key, size_t key_len )
{
	u32 blocks = ( key_len + SHA1_SIZE - 1 ) / SHA1_SIZE;
	u32 blk;
	u8 buf[SHA1_SIZE];

	for ( blk = 1; blk <= blocks; blk++ ) {
		pbkdf2_sha1_f ( passphrase, pass_len, salt, salt_len,
				iterations, blk, buf );
		if ( key_len <= SHA1_SIZE ) {
			memcpy ( key, buf, key_len );
			break;
		}

		memcpy ( key, buf, SHA1_SIZE );
		key_len -= SHA1_SIZE;
		key += SHA1_SIZE;
	}
}
