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