File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / crypto / xofs / xof_bitspender.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:44 2020 UTC (4 years, 3 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /*
    2:  * Copyright (C) 2014-2016 Andreas Steffen
    3:  * HSR Hochschule fuer Technik Rapperswil
    4:  *
    5:  * This program is free software; you can redistribute it and/or modify it
    6:  * under the terms of the GNU General Public License as published by the
    7:  * Free Software Foundation; either version 2 of the License, or (at your
    8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
    9:  *
   10:  * This program is distributed in the hope that it will be useful, but
   11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13:  * for more details.
   14:  */
   15: 
   16: #include "xof_bitspender.h"
   17: #include "mgf1.h"
   18: 
   19: typedef struct private_xof_bitspender_t private_xof_bitspender_t;
   20: 
   21: /**
   22:  * Private data structure for xof_bitspender_t object
   23:  */
   24: struct private_xof_bitspender_t {
   25: 	/**
   26: 	 * Public interface.
   27: 	 */
   28: 	xof_bitspender_t public;
   29: 
   30: 	/**
   31: 	 * Extended Output Function (XOF)
   32: 	 */
   33: 	xof_t *xof;
   34: 
   35: 	/**
   36: 	 * Length of the returned hash value in octets
   37: 	 */
   38: 	int hash_len;
   39: 
   40: 	/**
   41: 	 * Bit storage (accommodates up to 32 bits)
   42: 	 */
   43: 	uint32_t bits;
   44: 
   45: 	/**
   46: 	 * Number of available bits
   47: 	 */
   48: 	int bits_left;
   49: 
   50: 	/**
   51: 	 * Byte storage (accommodates up to 4 bytes)
   52: 	 */
   53: 	uint8_t bytes[4];
   54: 
   55: 	/**
   56: 	 * Number of available bytes
   57: 	 */
   58: 	int bytes_left;
   59: 
   60: 	/**
   61: 	 * Number of octets spent
   62: 	 */
   63: 	int octet_count;
   64: 
   65: };
   66: 
   67: static bool get_next_block(private_xof_bitspender_t *this, uint8_t *buffer)
   68: {
   69: 	if (!this->xof->get_bytes(this->xof, 4, buffer))
   70: 	{
   71: 		/* no block available */
   72: 		return FALSE;
   73: 	}
   74: 	this->octet_count += 4;
   75: 
   76: 	return TRUE;
   77: }
   78: 
   79: METHOD(xof_bitspender_t, get_bits, bool,
   80: 	private_xof_bitspender_t *this, int bits_needed, uint32_t *bits)
   81: {
   82: 	int bits_now;
   83: 
   84: 	*bits = 0x00000000;
   85: 
   86: 	if (bits_needed == 0)
   87: 	{
   88: 		/* trivial */
   89: 		return TRUE;
   90: 	}
   91: 	if (bits_needed > 32)
   92: 	{
   93: 		/* too many bits requested */
   94: 		return FALSE;
   95: 	}
   96: 
   97: 	while (bits_needed)
   98: 	{
   99: 		if (this->bits_left == 0)
  100: 		{
  101: 			uint8_t buf[4];
  102: 
  103: 			if (!get_next_block(this, buf))
  104: 			{
  105: 				return FALSE;
  106: 			}
  107: 			this->bits = untoh32(buf);
  108: 			this->bits_left = 32;
  109: 		}
  110: 		if (bits_needed > this->bits_left)
  111: 		{
  112: 			bits_now = this->bits_left;
  113: 			this->bits_left = 0;
  114: 			bits_needed -= bits_now;
  115: 		}
  116: 		else
  117: 		{
  118: 			bits_now = bits_needed;
  119: 			this->bits_left -= bits_needed;
  120: 			bits_needed = 0;
  121: 		}
  122: 		if (bits_now == 32)
  123: 		{
  124: 			*bits = this->bits;
  125: 		}
  126: 		else
  127: 		{
  128: 			*bits <<= bits_now;
  129: 			*bits |= this->bits >> this->bits_left;
  130: 			if (this->bits_left)
  131: 			{
  132: 				this->bits &= 0xffffffff >> (32 - this->bits_left);
  133: 			}
  134: 		}
  135: 	}
  136: 
  137: 	return TRUE;
  138: }
  139: 
  140: METHOD(xof_bitspender_t, get_byte, bool,
  141: 	private_xof_bitspender_t *this, uint8_t *byte)
  142: {
  143: 	if (this->bytes_left == 0)
  144: 	{
  145: 		if (!get_next_block(this, this->bytes))
  146: 		{
  147: 			return FALSE;
  148: 		}
  149: 		this->bytes_left = 4;
  150: 	}
  151: 	*byte = this->bytes[4 - this->bytes_left--];
  152: 
  153: 	return TRUE;
  154: }
  155: 
  156: METHOD(xof_bitspender_t, destroy, void,
  157: 	private_xof_bitspender_t *this)
  158: {
  159: 	DBG2(DBG_LIB, "%N generated %u octets", ext_out_function_names,
  160: 				   this->xof->get_type(this->xof), this->octet_count);
  161: 	memwipe(this->bytes, 4);
  162: 	this->xof->destroy(this->xof);
  163: 	free(this);
  164: }
  165: 
  166: /**
  167:  * See header.
  168:  */
  169: xof_bitspender_t *xof_bitspender_create(ext_out_function_t alg, chunk_t seed,
  170: 										bool hash_seed)
  171: {
  172: 	private_xof_bitspender_t *this;
  173: 	xof_t *xof;
  174: 
  175: 	xof = lib->crypto->create_xof(lib->crypto, alg);
  176: 	if (!xof)
  177: 	{
  178: 		return NULL;
  179: 	}
  180: 
  181: 	switch (alg)
  182: 	{
  183: 		case XOF_MGF1_SHA1:
  184: 		case XOF_MGF1_SHA256:
  185: 		case XOF_MGF1_SHA512:
  186: 		{
  187: 			mgf1_t *mgf1 = (mgf1_t*)xof;
  188: 
  189: 			mgf1->set_hash_seed(mgf1, hash_seed);
  190: 			break;
  191: 		}
  192: 		default:
  193: 			break;
  194: 	}
  195: 	if (!xof->set_seed(xof, seed))
  196: 	{
  197: 		xof->destroy(xof);
  198: 		return NULL;
  199: 	}
  200: 	DBG2(DBG_LIB, "%N is seeded with %u octets", ext_out_function_names,
  201: 				   alg, seed.len);
  202: 
  203: 	INIT(this,
  204: 		.public = {
  205: 			.get_bits = _get_bits,
  206: 			.get_byte = _get_byte,
  207: 			.destroy = _destroy,
  208: 		},
  209: 		.xof = xof,
  210: 	);
  211: 
  212: 	return &this->public;
  213: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>