Annotation of embedaddon/strongswan/src/libstrongswan/crypto/xofs/xof_bitspender.c, revision 1.1
1.1 ! misho 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>