struct SilcHmacStruct {
SilcHmacObject *hmac;
SilcHash hash;
- bool allocated_hash; /* TRUE if the hash was allocated */
unsigned char *key;
- uint32 key_len;
+ 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
/* List of dynamically registered HMACs. */
SilcDList silc_hmac_list = NULL;
+#endif /* SILC_EPOC */
/* Default hmacs for silc_hmac_register_default(). */
-SilcHmacObject silc_default_hmacs[] =
+const SilcHmacObject silc_default_hmacs[] =
{
{ "hmac-sha1-96", 12 },
{ "hmac-md5-96", 12 },
};
static void silc_hmac_init_internal(SilcHmac hmac, unsigned char *key,
- uint32 key_len)
+ 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;
}
/* Registers a new HMAC into the SILC. This function is used at the
initialization of the SILC. */
-bool silc_hmac_register(SilcHmacObject *hmac)
+bool silc_hmac_register(const SilcHmacObject *hmac)
{
+#ifndef SILC_EPOC
SilcHmacObject *new;
SILC_LOG_DEBUG(("Registering new HMAC `%s'", hmac->name));
silc_hmac_list = silc_dlist_init();
silc_dlist_add(silc_hmac_list, new);
+#endif /* SILC_EPOC */
return TRUE;
}
bool silc_hmac_unregister(SilcHmacObject *hmac)
{
+#ifndef SILC_EPOC
SilcHmacObject *entry;
SILC_LOG_DEBUG(("Unregistering HMAC"));
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);
}
}
+#endif /* SILC_EPOC */
return FALSE;
}
bool silc_hmac_register_default(void)
{
+#ifndef SILC_EPOC
int i;
for (i = 0; silc_default_hmacs[i].name; i++)
silc_hmac_register(&(silc_default_hmacs[i]));
+#endif /* SILC_EPOC */
+ 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;
}
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)
{
- SilcHmacObject *entry;
-
SILC_LOG_DEBUG(("Allocating new HMAC"));
/* Allocate the new object */
(*new_hmac)->hash = hash;
+#ifndef SILC_EPOC
if (silc_hmac_list) {
+ SilcHmacObject *entry;
silc_dlist_start(silc_hmac_list);
while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
if (!strcmp(entry->name, name)) {
}
}
}
+#else
+ {
+ /* On EPOC which don't have globals we check our constant hash list. */
+ int i;
+ for (i = 0; silc_default_hmacs[i].name; i++) {
+ if (!strcmp(silc_default_hmacs[i].name, name)) {
+ (*new_hmac)->hmac = (SilcHmacObject *)&(silc_default_hmacs[i]);
+ return TRUE;
+ }
+ }
+ }
+#endif /* SILC_EPOC */
silc_free(*new_hmac);
*new_hmac = NULL;
silc_free(hmac->key);
}
- silc_free(hmac->hash_context);
silc_free(hmac);
}
}
/* Returns the length of the MAC that the HMAC will produce. */
-uint32 silc_hmac_len(SilcHmac hmac)
+SilcUInt32 silc_hmac_len(SilcHmac hmac)
{
return hmac->hmac->len;
}
bool silc_hmac_is_supported(const char *name)
{
+#ifndef SILC_EPOC
SilcHmacObject *entry;
if (!name)
return TRUE;
}
}
-
+#else
+ {
+ int i;
+ for (i = 0; silc_default_hmacs[i].name; i++)
+ if (!strcmp(silc_default_hmacs[i].name, name))
+ return TRUE;
+ }
+#endif /* SILC_EPOC */
return FALSE;
}
{
SilcHmacObject *entry;
char *list = NULL;
- int len;
+ int len = 0;
- len = 0;
+#ifndef SILC_EPOC
if (silc_hmac_list) {
silc_dlist_start(silc_hmac_list);
while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
memcpy(list + len, ",", 1);
len++;
}
- list[len - 1] = 0;
}
+#else
+ {
+ int i;
+ for (i = 0; silc_default_hmacs[i].name; i++) {
+ entry = (SilcHmacObject *)&(silc_default_hmacs[i]);
+ len += strlen(entry->name);
+ list = silc_realloc(list, len + 1);
+
+ memcpy(list + (len - strlen(entry->name)),
+ entry->name, strlen(entry->name));
+ memcpy(list + len, ",", 1);
+ len++;
+ }
+ }
+#endif /* SILC_EPOC */
+
+ list[len - 1] = 0;
return list;
}
/* Sets the HMAC key used in the HMAC creation */
void silc_hmac_set_key(SilcHmac hmac, const unsigned char *key,
- uint32 key_len)
+ SilcUInt32 key_len)
{
if (hmac->key) {
memset(hmac->key, 0, hmac->key_len);
uses the internal key set with silc_hmac_set_key. */
void silc_hmac_make(SilcHmac hmac, unsigned char *data,
- uint32 data_len, unsigned char *return_hash,
- uint32 *return_len)
+ SilcUInt32 data_len, unsigned char *return_hash,
+ SilcUInt32 *return_len)
{
SILC_LOG_DEBUG(("Making HMAC for message"));
key. The key is sent as argument to the function. */
void silc_hmac_make_with_key(SilcHmac hmac, unsigned char *data,
- uint32 data_len,
- unsigned char *key, uint32 key_len,
+ SilcUInt32 data_len,
+ unsigned char *key, SilcUInt32 key_len,
unsigned char *return_hash,
- uint32 *return_len)
+ SilcUInt32 *return_len)
{
SILC_LOG_DEBUG(("Making HMAC for message"));
routine allows these dangerous truncations. */
void silc_hmac_make_truncated(SilcHmac hmac, unsigned char *data,
- uint32 data_len,
- uint32 truncated_len,
+ SilcUInt32 data_len,
+ SilcUInt32 truncated_len,
unsigned char *return_hash)
{
unsigned char hvalue[20];
/* Same as above but with specific key */
void silc_hmac_init_with_key(SilcHmac hmac, const unsigned char *key,
- uint32 key_len)
+ 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. */
void silc_hmac_update(SilcHmac hmac, const unsigned char *data,
- uint32 data_len)
+ 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. */
void silc_hmac_final(SilcHmac hmac, unsigned char *return_hash,
- uint32 *return_len)
+ SilcUInt32 *return_len)
{
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));