* Number of available bits
*/
int bits_left;
+
+ /**
+ * Byte storage (accomodates up to 4 bytes)
+ */
+ uint8_t bytes[4];
+
+ /**
+ * Number of available bytes
+ */
+ int bytes_left;
+
};
-METHOD(mgf1_bitspender_t, get_bits, uint32_t,
- private_mgf1_bitspender_t *this, int bits_needed)
+METHOD(mgf1_bitspender_t, get_bits, bool,
+ private_mgf1_bitspender_t *this, int bits_needed, uint32_t *bits)
{
- uint32_t bits = 0x00000000;
int bits_now;
- if (bits_needed > 31)
+ if (bits_needed > 32)
{
/* too many bits requested */
- return MGF1_BITSPENDER_ERROR;
+ return FALSE;
}
+ *bits = 0x00000000;
while (bits_needed)
{
this->octets))
{
/* no block available */
- return MGF1_BITSPENDER_ERROR;
+ return FALSE;
}
this->octets_left = this->hash_len;
this->octets_count += this->hash_len;
bits_now = this->bits_left;
this->bits_left = 0;
bits_needed -= bits_now;
- bits <<= bits_now;
- bits |= this->bits;
+ *bits <<= bits_now;
+ *bits |= this->bits;
}
else
{
bits_now = bits_needed;
this->bits_left -= bits_needed;
bits_needed = 0;
- bits <<= bits_now;
- bits |= this->bits >> this->bits_left;
+ *bits <<= bits_now;
+ *bits |= this->bits >> this->bits_left;
this->bits &= 0xffffffff >> (32 - this->bits_left);
}
}
- return bits;
+ return TRUE;
}
+METHOD(mgf1_bitspender_t, get_byte, bool,
+ private_mgf1_bitspender_t *this, uint8_t *byte)
+{
+ if (this->bytes_left == 0)
+ {
+ if (this->octets_left == 0)
+ {
+ /* get another block from MGF1 */
+ if (!this->mgf1->get_mask(this->mgf1, this->hash_len, this->octets))
+ {
+ /* no block available */
+ return FALSE;
+ }
+ this->octets_left = this->hash_len;
+ this->octets_count += this->hash_len;
+ }
+ memcpy(this->bytes, this->octets + this->hash_len - this->octets_left, 4);
+ this->bytes_left = 4;
+ this->octets_left -= 4;
+ }
+ *byte = this->bytes[4 - this->bytes_left--];
+
+ return TRUE;
+}
METHOD(mgf1_bitspender_t, destroy, void,
private_mgf1_bitspender_t *this)
INIT(this,
.public = {
.get_bits = _get_bits,
+ .get_byte = _get_byte,
.destroy = _destroy,
},
.mgf1 = mgf1,
/**
* @defgroup mgf1_bitspender mgf1_bitspender
- * @{ @ingroup bliss_p
+ * @{ @ingroup mgf1_p
*/
#ifndef MGF1_BITSPENDER_H_
typedef struct mgf1_bitspender_t mgf1_bitspender_t;
-#define MGF1_BITSPENDER_ERROR 0xffffffff
-
/**
- * Generates a given number of pseudo-random bits at a time using MFG1
+ * Generates a given number of pseudo-random bits at a time using MGF1
*/
struct mgf1_bitspender_t {
/**
* Get pseudo-random bits
*
- * @param bits_needed Number of needed bits (1..31)
- * @result Return between 1 and 31 pseudo-random bits
+ * @param bits_needed Number of needed bits (1..32)
+ * @param bits Pseudo-random bits
+ * @result FALSE if internal MGF1 error occurred
+ */
+ bool (*get_bits)(mgf1_bitspender_t *this, int bits_needed, uint32_t *bits);
+
+ /**
+ * Get a pseudo-random byte
+ *
+ * @param byte Pseudo-random byte
+ * @result FALSE if internal MGF1 error occurred
*/
- uint32_t (*get_bits)(mgf1_bitspender_t *this, int bits_needed);
+ bool (*get_byte)(mgf1_bitspender_t *this, uint8_t *byte);
/**
* Destroy mgf1_bitspender_t object
chunk_t seed;
chunk_t hashed_seed;
chunk_t mask;
- uint32_t bits[15];
+ uint32_t bits[20];
} mgf1_test_t;
/**
0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C,
0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92,
0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14),
- { 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403 },
+ { 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403,
+ 0x63, 0x2B, 0xC9, 0x17, 0x56 },
},
{ HASH_SHA256, 32, 64, 32, 33, 40,
chunk_from_chars(
0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6,
0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95,
0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42),
- { 0, 1, 3, 4, 4, 12, 32, 36, 253, 331, 2, 1640, 503, 6924, 580 }
+ { 0, 1, 3, 4, 4, 12, 32, 36, 253, 331, 2, 1640, 503, 6924, 580,
+ 0xCB, 0x35, 0x3C, 0xDC, 0xAD }
}
};
{
mgf1_bitspender_t *bitspender;
uint32_t bits;
+ uint8_t byte;
int j;
bitspender = mgf1_bitspender_create(HASH_UNKNOWN,
for (j = 0; j < 15; j++)
{
- bits = bitspender->get_bits(bitspender, j);
+ ck_assert(bitspender->get_bits(bitspender, j, &bits));
DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j, mgf1_tests[_i].bits[j],
bits);
ck_assert(bits == mgf1_tests[_i].bits[j]);
}
- bits = bitspender->get_bits(bitspender, 32);
- ck_assert(bits == MGF1_BITSPENDER_ERROR);
+ ck_assert(!bitspender->get_bits(bitspender, 33, &bits));
+
+ for (j = 15; j < 20; j++)
+ {
+ ck_assert(bitspender->get_byte(bitspender, &byte));
+ DBG1(DBG_LIB, "bits[%d] = 0x%02x, byte = 0x%02x", j,
+ mgf1_tests[_i].bits[j], byte);
+ ck_assert(byte == mgf1_tests[_i].bits[j]);
+ }
bitspender->destroy(bitspender);
}