struct SilcHmacStruct {
SilcHmacObject *hmac;
SilcHash hash;
- bool allocated_hash; /* TRUE if the hash was allocated */
unsigned char *key;
SilcUInt32 key_len;
unsigned char inner_pad[64];
unsigned char outer_pad[64];
- void *hash_context;
+ bool allocated_hash; /* TRUE if the hash was allocated */
};
#ifndef SILC_EPOC
SilcUInt32 key_len)
{
SilcHash hash = hmac->hash;
+ SilcUInt32 block_len;
unsigned char hvalue[20];
int i;
memset(hmac->inner_pad, 0, sizeof(hmac->inner_pad));
memset(hmac->outer_pad, 0, sizeof(hmac->outer_pad));
+ block_len = silc_hash_block_len(hash);
+
/* If the key length is more than block size of the hash function, the
key is hashed. */
- if (key_len > hash->hash->block_len) {
+ if (key_len > block_len) {
silc_hash_make(hash, key, key_len, hvalue);
key = hvalue;
- key_len = hash->hash->hash_len;
+ key_len = silc_hash_len(hash);
}
/* Copy the key into the pads */
memcpy(hmac->outer_pad, key, key_len);
/* XOR the key with pads */
- for (i = 0; i < hash->hash->block_len; i++) {
+ for (i = 0; i < block_len; i++) {
hmac->inner_pad[i] ^= 0x36;
hmac->outer_pad[i] ^= 0x5c;
}
while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
if (hmac == SILC_ALL_HMACS || entry == hmac) {
silc_dlist_del(silc_hmac_list, entry);
+ silc_free(entry->name);
+ silc_free(entry);
if (silc_dlist_count(silc_hmac_list) == 0) {
silc_dlist_uninit(silc_hmac_list);
return TRUE;
}
+bool silc_hmac_unregister_all(void)
+{
+#ifndef SILC_EPOC
+ SilcHmacObject *entry;
+
+ if (!silc_hmac_list)
+ return FALSE;
+
+ silc_dlist_start(silc_hmac_list);
+ while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
+ silc_hmac_unregister(entry);
+ if (!silc_hmac_list)
+ break;
+ }
+#endif /* SILC_EPOC */
+ return TRUE;
+}
+
/* Allocates a new SilcHmac object of name of `name'. The `hash' may
be provided as argument. If provided it is used as the hash function
of the HMAC. If it is NULL then the hash function is allocated and
the name of the hash algorithm is derived from the `name'. */
-bool silc_hmac_alloc(char *name, SilcHash hash, SilcHmac *new_hmac)
+bool silc_hmac_alloc(const char *name, SilcHash hash, SilcHmac *new_hmac)
{
SILC_LOG_DEBUG(("Allocating new HMAC"));
silc_free(hmac->key);
}
- silc_free(hmac->hash_context);
silc_free(hmac);
}
}
SilcUInt32 key_len)
{
SilcHash hash = hmac->hash;
-
- silc_hmac_init_internal(hmac, hmac->key, hmac->key_len);
-
- if (!hmac->hash_context)
- hmac->hash_context = silc_calloc(1, hash->hash->context_len());
-
- hash->hash->init(hmac->hash_context);
- hash->hash->update(hmac->hash_context, hmac->inner_pad,
- hash->hash->block_len);
+ silc_hmac_init_internal(hmac, (unsigned char *)key, key_len);
+ silc_hash_init(hash);
+ silc_hash_update(hash, hmac->inner_pad, silc_hash_block_len(hash));
}
/* Add data to be used in the MAC computation. */
SilcUInt32 data_len)
{
SilcHash hash = hmac->hash;
- hash->hash->update(hmac->hash_context, (unsigned char *)data, data_len);
+ silc_hash_update(hash, data, data_len);
}
/* Compute the final MAC. */
SilcHash hash = hmac->hash;
unsigned char mac[20];
- hash->hash->final(hmac->hash_context, mac);
- hash->hash->init(hmac->hash_context);
- hash->hash->update(hmac->hash_context, hmac->outer_pad,
- hash->hash->block_len);
- hash->hash->update(hmac->hash_context, mac, hash->hash->hash_len);
- hash->hash->final(hmac->hash_context, mac);
+ silc_hash_final(hash, mac);
+ silc_hash_init(hash);
+ silc_hash_update(hash, hmac->outer_pad, silc_hash_block_len(hash));
+ silc_hash_update(hash, mac, silc_hash_len(hash));
+ silc_hash_final(hash, mac);
memcpy(return_hash, mac, hmac->hmac->len);
memset(mac, 0, sizeof(mac));