/*
- silchmac.c
+ silchmac.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1999 - 2001 Pekka Riikonen
+ Copyright (C) 1999 - 2005 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
struct SilcHmacStruct {
SilcHmacObject *hmac;
SilcHash hash;
-
- unsigned char *key;
- SilcUInt32 key_len;
-
unsigned char inner_pad[64];
unsigned char outer_pad[64];
- bool allocated_hash; /* TRUE if the hash was allocated */
+ unsigned char *key;
+ unsigned int key_len : 31;
+ unsigned int allocated_hash : 1; /* TRUE if the hash was allocated */
};
#ifndef SILC_EPOC
/* Default hmacs for silc_hmac_register_default(). */
const SilcHmacObject silc_default_hmacs[] =
{
+ { "hmac-sha256-96", 12 },
{ "hmac-sha1-96", 12 },
{ "hmac-md5-96", 12 },
+ { "hmac-sha256", 32 },
{ "hmac-sha1", 20 },
{ "hmac-md5", 16 },
{
SilcHash hash = hmac->hash;
SilcUInt32 block_len;
- unsigned char hvalue[20];
+ unsigned char hvalue[SILC_HASH_MAXLEN];
int i;
memset(hmac->inner_pad, 0, sizeof(hmac->inner_pad));
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 FALSE;
}
-/* Function that registers all the default hmacs (all builtin ones).
+/* Function that registers all the default hmacs (all builtin ones).
The application may use this to register the default hmacs if
specific hmacs in any specific order is not wanted. */
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_dlist_start(silc_hmac_list);
while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
if (!strcmp(entry->name, name)) {
- (*new_hmac)->hmac = entry;
+ (*new_hmac)->hmac = entry;
return TRUE;
}
}
if (!name)
return FALSE;
-
+
if (silc_hmac_list) {
silc_dlist_start(silc_hmac_list);
while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
while ((entry = silc_dlist_get(silc_hmac_list)) != SILC_LIST_END) {
len += strlen(entry->name);
list = silc_realloc(list, len + 1);
-
- memcpy(list + (len - strlen(entry->name)),
+
+ memcpy(list + (len - strlen(entry->name)),
entry->name, strlen(entry->name));
memcpy(list + len, ",", 1);
len++;
entry = (SilcHmacObject *)&(silc_default_hmacs[i]);
len += strlen(entry->name);
list = silc_realloc(list, len + 1);
-
- memcpy(list + (len - strlen(entry->name)),
+
+ memcpy(list + (len - strlen(entry->name)),
entry->name, strlen(entry->name));
memcpy(list + len, ",", 1);
len++;
key. The key is sent as argument to the function. */
void silc_hmac_make_with_key(SilcHmac hmac, unsigned char *data,
- SilcUInt32 data_len,
+ SilcUInt32 data_len,
unsigned char *key, SilcUInt32 key_len,
unsigned char *return_hash,
SilcUInt32 *return_len)
/* Creates the HMAC just as above except that the hash value is truncated
to the truncated_len sent as argument. NOTE: One should not truncate to
- less than half of the length of original hash value. However, this
+ less than half of the length of original hash value. However, this
routine allows these dangerous truncations. */
void silc_hmac_make_truncated(SilcHmac hmac, unsigned char *data,
SilcUInt32 truncated_len,
unsigned char *return_hash)
{
- unsigned char hvalue[20];
+ unsigned char hvalue[SILC_HASH_MAXLEN];
SILC_LOG_DEBUG(("Making HMAC for message"));
SilcUInt32 key_len)
{
SilcHash hash = hmac->hash;
- silc_hmac_init_internal(hmac, hmac->key, hmac->key_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));
}
SilcUInt32 *return_len)
{
SilcHash hash = hmac->hash;
- unsigned char mac[20];
+ unsigned char mac[SILC_HASH_MAXLEN];
silc_hash_final(hash, mac);
silc_hash_init(hash);