/**
* build a cookie
*/
-static chunk_t cookie_build(private_receiver_t *this, message_t *message,
- u_int32_t t, chunk_t secret)
+static bool cookie_build(private_receiver_t *this, message_t *message,
+ u_int32_t t, chunk_t secret, chunk_t *cookie)
{
u_int64_t spi = message->get_initiator_spi(message);
host_t *ip = message->get_source(message);
input = chunk_cata("cccc", ip->get_address(ip), chunk_from_thing(spi),
chunk_from_thing(t), secret);
hash = chunk_alloca(this->hasher->get_hash_size(this->hasher));
- this->hasher->get_hash(this->hasher, input, hash.ptr);
- return chunk_cat("cc", chunk_from_thing(t), hash);
+ if (!this->hasher->get_hash(this->hasher, input, hash.ptr))
+ {
+ return FALSE;
+ }
+ *cookie = chunk_cat("cc", chunk_from_thing(t), hash);
+ return TRUE;
}
/**
}
/* compare own calculation against received */
- reference = cookie_build(this, message, t, secret);
+ if (!cookie_build(this, message, t, secret, &reference))
+ {
+ return FALSE;
+ }
if (chunk_equals(reference, cookie))
{
chunk_free(&reference);
{
chunk_t cookie;
- cookie = cookie_build(this, message, now - this->secret_offset,
- chunk_from_thing(this->secret));
DBG2(DBG_NET, "received packet from: %#H to %#H",
message->get_source(message),
message->get_destination(message));
+ if (!cookie_build(this, message, now - this->secret_offset,
+ chunk_from_thing(this->secret), &cookie))
+ {
+ return TRUE;
+ }
DBG2(DBG_NET, "sending COOKIE notify to %H",
message->get_source(message));
send_notify(message, IKEV2_MAJOR_VERSION, IKE_SA_INIT, COOKIE, cookie);
{
return FALSE;
}
- this->hasher->get_hash(this->hasher, encoding, buf);
+ if (!this->hasher->get_hash(this->hasher, encoding, buf))
+ {
+ free(encoding.ptr);
+ return FALSE;
+ }
free(encoding.ptr);
chunk_to_hex(chunk_create(buf, this->hasher->get_hash_size(this->hasher)),
hex, FALSE);
while (c < data.ptr + data.len)
{
/* b(i) = MD5(S + c(i-1)) */
- this->hasher->get_hash(this->hasher, this->secret, NULL);
- this->hasher->get_hash(this->hasher, seed, b);
+ if (!this->hasher->get_hash(this->hasher, this->secret, NULL) ||
+ !this->hasher->get_hash(this->hasher, seed, b))
+ {
+ free(data.ptr);
+ return chunk_empty;
+ }
/* c(i) = b(i) xor p(1) */
memxor(c, b, HASH_SIZE_MD5);
/* build Response-Authenticator */
msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
- hasher->get_hash(hasher, msg, NULL);
- hasher->get_hash(hasher, secret, this->msg->authenticator);
+ if (!hasher->get_hash(hasher, msg, NULL) ||
+ !hasher->get_hash(hasher, secret, this->msg->authenticator))
+ {
+ return FALSE;
+ }
}
return TRUE;
}
}
/* verify Response-Authenticator */
- hasher->get_hash(hasher, msg, NULL);
- hasher->get_hash(hasher, secret, buf);
- if (!memeq(buf, res_auth, HASH_SIZE_MD5))
+ if (!hasher->get_hash(hasher, msg, NULL) ||
+ !hasher->get_hash(hasher, secret, buf) ||
+ !memeq(buf, res_auth, HASH_SIZE_MD5))
{
DBG1(DBG_CFG, "RADIUS Response-Authenticator verification failed");
return FALSE;
while (c < C.ptr + C.len)
{
/* b(i) = MD5(S + c(i-1)) */
- this->hasher->get_hash(this->hasher, this->secret, NULL);
- this->hasher->get_hash(this->hasher, seed, p);
+ if (!this->hasher->get_hash(this->hasher, this->secret, NULL) ||
+ !this->hasher->get_hash(this->hasher, seed, p))
+ {
+ return chunk_empty;
+ }
/* p(i) = b(i) xor c(1) */
memxor(p, c, HASH_SIZE_MD5);
/* For SIM: MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version)
* For AKA: MK = SHA1(Identity|IK|CK) */
- this->hasher->get_hash(this->hasher, id->get_encoding(id), NULL);
+ if (!this->hasher->get_hash(this->hasher, id->get_encoding(id), NULL))
+ {
+ return FALSE;
+ }
this->hasher->allocate_hash(this->hasher, data, mk);
DBG3(DBG_LIB, "MK %B", mk);
chunk_t str;
int i;
- this->hasher->get_hash(this->hasher, id->get_encoding(id), NULL);
- this->hasher->get_hash(this->hasher, counter, NULL);
- this->hasher->get_hash(this->hasher, nonce_s, NULL);
- this->hasher->get_hash(this->hasher, mk, xkey);
+ if (!this->hasher->get_hash(this->hasher, id->get_encoding(id), NULL) ||
+ !this->hasher->get_hash(this->hasher, counter, NULL) ||
+ !this->hasher->get_hash(this->hasher, nonce_s, NULL) ||
+ !this->hasher->get_hash(this->hasher, mk, xkey))
+ {
+ return FALSE;
+ }
/* MSK | EMSK = prf() | prf() | prf() | prf() */
if (!this->prf->set_key(this->prf, chunk_create(xkey, sizeof(xkey))))
start_timing(&start);
while (end_timing(&start) < this->bench_time)
{
- hasher->get_hash(hasher, buf, hash);
- runs++;
+ if (hasher->get_hash(hasher, buf, hash))
+ {
+ runs++;
+ }
}
free(buf.ptr);
hasher->destroy(hasher);
}
/* hash to existing buffer */
memset(hash.ptr, 0, hash.len);
- hasher->get_hash(hasher, data, hash.ptr);
+ if (!hasher->get_hash(hasher, data, hash.ptr))
+ {
+ failed = TRUE;
+ }
if (!memeq(vector->hash, hash.ptr, hash.len))
{
failed = TRUE;
{
memset(hash.ptr, 0, hash.len);
hasher->allocate_hash(hasher, chunk_create(data.ptr, 1), NULL);
- hasher->get_hash(hasher, chunk_create(data.ptr + 1, 1), NULL);
- hasher->get_hash(hasher, chunk_skip(data, 2), hash.ptr);
- if (!memeq(vector->hash, hash.ptr, hash.len))
+ if (!hasher->get_hash(hasher, chunk_create(data.ptr + 1, 1), NULL) ||
+ !hasher->get_hash(hasher, chunk_skip(data, 2), hash.ptr) ||
+ !memeq(vector->hash, hash.ptr, hash.len))
{
failed = TRUE;
}
* Generic interface for all hash functions.
*/
struct hasher_t {
+
/**
* Hash data and write it in the buffer.
*
*
* @param data data to hash
* @param hash pointer where the hash will be written
+ * @return TRUE if hash created successfully
*/
- void (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash);
+ __attribute__((warn_unused_result))
+ bool (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash);
/**
* Hash data and allocate space for the hash.
this->ops->reset(this->ops);
}
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_af_alg_hasher_t *this, chunk_t chunk, u_int8_t *hash)
{
this->ops->hash(this->ops, chunk, hash, this->size);
+ return TRUE;
}
METHOD(hasher_t, allocate_hash, void,
gcry_md_reset(this->hd);
}
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_gcrypt_hasher_t *this, chunk_t chunk, u_int8_t *hash)
{
gcry_md_write(this->hd, chunk.ptr, chunk.len);
memcpy(hash, gcry_md_read(this->hd, 0), get_hash_size(this));
gcry_md_reset(this->hd);
}
+ return TRUE;
}
METHOD(hasher_t, allocate_hash, void,
if (out == NULL)
{
/* append data to inner */
- this->h->get_hash(this->h, data, NULL);
+ return this->h->get_hash(this->h, data, NULL);
}
- else
- {
- /* append and do outer hash */
- inner.ptr = buffer;
- inner.len = this->h->get_hash_size(this->h);
-
- /* complete inner */
- this->h->get_hash(this->h, data, buffer);
- /* do outer */
- this->h->get_hash(this->h, this->opaded_key, NULL);
- this->h->get_hash(this->h, inner, out);
+ /* append and do outer hash */
+ inner.ptr = buffer;
+ inner.len = this->h->get_hash_size(this->h);
- /* reinit for next call */
- this->h->get_hash(this->h, this->ipaded_key, NULL);
- }
- return TRUE;
+ /* complete inner, do outer and reinit for next call */
+ return this->h->get_hash(this->h, data, buffer) &&
+ this->h->get_hash(this->h, this->opaded_key, NULL) &&
+ this->h->get_hash(this->h, inner, out) &&
+ this->h->get_hash(this->h, this->ipaded_key, NULL);
}
METHOD(mac_t, get_mac_size, size_t,
if (key.len > this->b)
{
/* if key is too long, it will be hashed */
- this->h->get_hash(this->h, key, buffer);
+ if (!this->h->get_hash(this->h, key, buffer))
+ {
+ return FALSE;
+ }
}
else
{
/* begin hashing of inner pad */
this->h->reset(this->h);
- this->h->get_hash(this->h, this->ipaded_key, NULL);
-
- return TRUE;
+ return this->h->get_hash(this->h, this->ipaded_key, NULL);
}
METHOD(mac_t, destroy, void,
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_md4_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
MD4Update(this, chunk.ptr, chunk.len);
MD4Final(this, buffer);
this->public.hasher_interface.reset(&(this->public.hasher_interface));
}
+ return TRUE;
}
METHOD(hasher_t, allocate_hash, void,
}
}
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
MD5Update(this, chunk.ptr, chunk.len);
MD5Final(this, buffer);
this->public.hasher_interface.reset(&(this->public.hasher_interface));
}
+ return TRUE;
}
METHOD(hasher_t, allocate_hash, void,
EVP_DigestInit_ex(this->ctx, this->hasher, NULL);
}
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_openssl_hasher_t *this, chunk_t chunk, u_int8_t *hash)
{
- EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len);
+ if (EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len) != 1)
+ {
+ return FALSE;
+ }
if (hash)
{
- EVP_DigestFinal_ex(this->ctx, hash, NULL);
+ if (EVP_DigestFinal_ex(this->ctx, hash, NULL) != 1)
+ {
+ return FALSE;
+ }
reset(this);
}
+ return TRUE;
}
METHOD(hasher_t, allocate_hash, void,
chunk_free(&this->data);
}
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_padlock_sha1_hasher_t *this, chunk_t chunk, u_int8_t *hash)
{
if (hash)
{
append_data(this, chunk);
}
+ return TRUE;
}
METHOD(hasher_t, allocate_hash, void,
}
hash.len = hasher->get_hash_size(hasher);
hash.ptr = alloca(hash.len);
- hasher->get_hash(hasher, passphrase, NULL);
- hasher->get_hash(hasher, salt, hash.ptr);
+ if (!hasher->get_hash(hasher, passphrase, NULL) ||
+ !hasher->get_hash(hasher, salt, hash.ptr))
+ {
+ return FAILED;
+ }
memcpy(key.ptr, hash.ptr, hash.len);
if (key.len > hash.len)
{
- hasher->get_hash(hasher, hash, NULL);
- hasher->get_hash(hasher, passphrase, NULL);
- hasher->get_hash(hasher, salt, hash.ptr);
+ if (!hasher->get_hash(hasher, hash, NULL) ||
+ !hasher->get_hash(hasher, passphrase, NULL) ||
+ !hasher->get_hash(hasher, salt, hash.ptr))
+ {
+ return FAILED;
+ }
memcpy(key.ptr + hash.len, hash.ptr, key.len - hash.len);
}
hasher->destroy(hasher);
/**
* Save the Operation state to host memory
*/
-static void save_state(private_pkcs11_hasher_t *this)
+static bool save_state(private_pkcs11_hasher_t *this)
{
CK_RV rv;
continue;
case CKR_OK:
this->have_state = TRUE;
- return;
+ return TRUE;
default:
break;
}
break;
}
DBG1(DBG_CFG, "C_GetOperationState() failed: %N", ck_rv_names, rv);
- abort();
+ return FALSE;
}
/**
* Load the Operation state from host memory
*/
-static void load_state(private_pkcs11_hasher_t *this)
+static bool load_state(private_pkcs11_hasher_t *this)
{
CK_RV rv;
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_SetOperationState() failed: %N", ck_rv_names, rv);
- abort();
+ return FALSE;
}
this->have_state = FALSE;
+ return TRUE;
}
METHOD(hasher_t, reset, void,
this->have_state = FALSE;
}
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_pkcs11_hasher_t *this, chunk_t chunk, u_int8_t *hash)
{
CK_RV rv;
this->mutex->lock(this->mutex);
if (this->have_state)
{
- load_state(this);
+ if (!load_state(this))
+ {
+ this->mutex->unlock(this->mutex);
+ return FALSE;
+ }
}
else
{
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_DigestInit() failed: %N", ck_rv_names, rv);
- abort();
+ this->mutex->unlock(this->mutex);
+ return FALSE;
}
}
if (chunk.len)
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_DigestUpdate() failed: %N", ck_rv_names, rv);
- abort();
+ this->mutex->unlock(this->mutex);
+ return FALSE;
}
}
if (hash)
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_DigestFinal() failed: %N", ck_rv_names, rv);
- abort();
+ this->mutex->unlock(this->mutex);
+ return FALSE;
}
}
else
{
- save_state(this);
+ if (!save_state(this))
+ {
+ this->mutex->unlock(this->mutex);
+ return FALSE;
+ }
}
this->mutex->unlock(this->mutex);
+ return TRUE;
}
METHOD(hasher_t, allocate_hash, void,
u_int64_t i;
hash = chunk_alloca(hasher->get_hash_size(hasher));
- hasher->get_hash(hasher, password, NULL);
- hasher->get_hash(hasher, salt, hash.ptr);
+ if (!hasher->get_hash(hasher, password, NULL) ||
+ !hasher->get_hash(hasher, salt, hash.ptr))
+ {
+ return FALSE;
+ }
for (i = 1; i < iterations; i++)
{
- hasher->get_hash(hasher, hash, hash.ptr);
+ if (!hasher->get_hash(hasher, hash, hash.ptr))
+ {
+ return FALSE;
+ }
}
memcpy(key.ptr, hash.ptr, key.len);
this->count[1] = 0;
}
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
SHA1Update(this, chunk.ptr, chunk.len);
SHA1Final(this, buffer);
reset(this);
}
+ return TRUE;
}
METHOD(hasher_t, allocate_hash, void,
this->sha_bufCnt = 0;
}
-METHOD(hasher_t, get_hash224, void,
+METHOD(hasher_t, get_hash224, bool,
private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
sha256_write(this, chunk.ptr, chunk.len);
memcpy(buffer, this->sha_out, HASH_SIZE_SHA224);
reset224(this);
}
+ return TRUE;
}
-METHOD(hasher_t, get_hash256, void,
+METHOD(hasher_t, get_hash256, bool,
private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
sha256_write(this, chunk.ptr, chunk.len);
memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
reset256(this);
}
+ return TRUE;
}
-METHOD(hasher_t, get_hash384, void,
+METHOD(hasher_t, get_hash384, bool,
private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
sha512_write(this, chunk.ptr, chunk.len);
memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
reset384(this);
}
+ return TRUE;
}
-METHOD(hasher_t, get_hash512, void,
+METHOD(hasher_t, get_hash512, bool,
private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
sha512_write(this, chunk.ptr, chunk.len);
memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
reset512(this);
}
+ return TRUE;
}
METHOD(hasher_t, allocate_hash224, void,
char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
- if (!md5)
+ if (!md5 || !md5->get_hash(md5, data, buf))
{
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5);
+ DESTROY_IF(md5);
return FALSE;
}
- md5->get_hash(md5, data, buf);
md5->destroy(md5);
sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (!sha1)
+ if (!sha1 || !sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5))
{
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1);
+ DESTROY_IF(sha1);
return FALSE;
}
- sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5);
sha1->destroy(sha1);
*hash = chunk_clone(chunk_from_thing(buf));
data = chunk_alloca(username_len + password_len);
memcpy(data.ptr, username, username_len);
memcpy(data.ptr + username_len, password, password_len);
- hasher->get_hash(hasher, data, hash.ptr);
+ if (!hasher->get_hash(hasher, data, hash.ptr))
+ {
+ hasher->destroy(hasher);
+ return 0;
+ }
hasher->destroy(hasher);
hex_str = chunk_to_hex(hash, NULL, FALSE);
hasher_t *hasher;
hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
- hasher->get_hash(hasher, pkcs10, digest.ptr);
+ if (!hasher || !hasher->get_hash(hasher, pkcs10, digest.ptr))
+ {
+ DESTROY_IF(hasher);
+ return chunk_empty;
+ }
hasher->destroy(hasher);
return chunk_to_hex(digest, NULL, FALSE);
asn1_bitstring("m", keyEncoding));
hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
- hasher->get_hash(hasher, keyInfo, digest.ptr);
- hasher->destroy(hasher);
+ if (!hasher || !hasher->get_hash(hasher, keyInfo, digest.ptr))
+ {
+ memset(digest.ptr, 0, digest.len);
+ }
+ DESTROY_IF(hasher);
free(keyInfo.ptr);
/* is the most significant bit of the digest set? */