Return to xof_bitspender.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / crypto / xofs |
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: }