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