From: Pekka Riikonen Date: Sat, 15 Jun 2002 19:38:36 +0000 (+0000) Subject: ROBODoc documented the SILC Hash Interface and improved X-Git-Tag: silc.toolkit.0.9.2~3 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=38d89c8cd04b2b9b7e487230420bbf21d26ac722 ROBODoc documented the SILC Hash Interface and improved the interface a bit too. --- diff --git a/CHANGES b/CHANGES index 715fed19..64943042 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,11 @@ Sat Jun 15 18:23:39 EEST 2002 Pekka Riikonen server statistics into /tmp directory. Affected file is silcd/silcd.c. + * ROBODoc documented the lib/silccrypt/silchash.h. Improved + the SILC Hash Interface also. Added new functions + silc_hash_get_name, silc_hash_init, silc_hash_update and + silc_hash_final. Affected file lib/silccrypt/silchash.c. + Sat Jun 15 12:09:14 EEST 2002 Pekka Riikonen * Added some better info printing for client during connecting. diff --git a/TODO b/TODO index 737c025e..c09bd0be 100644 --- a/TODO +++ b/TODO @@ -55,8 +55,6 @@ Manual (Do these to 0.9.x). o ROBOdoc documenting missing from lib/silcutil/silcfileutil.h. - o ROBOdoc documenting missing from lib/silccrypt/silchash.h. - o ROBOdoc documenting missing from lib/silccrypt/silccipher.h. o ROBOdoc documenting missing from lib/silccrypt/silcpkcs.h. diff --git a/apps/silcd/protocol.c b/apps/silcd/protocol.c index 6aa3ac93..75eb86ed 100644 --- a/apps/silcd/protocol.c +++ b/apps/silcd/protocol.c @@ -291,13 +291,14 @@ int silc_server_protocol_ke_set_keys(SilcServer server, idata->rekey->ske_group = silc_ske_group_get_number(group); /* Save the hash */ - if (!silc_hash_alloc(hash->hash->name, &idata->hash)) { + if (!silc_hash_alloc(silc_hash_get_name(hash), &idata->hash)) { silc_cipher_free(idata->send_key); silc_cipher_free(idata->receive_key); silc_hmac_free(idata->hmac_send); silc_hmac_free(idata->hmac_receive); silc_free(conn_data); - SILC_LOG_ERROR(("Cannot allocate algorithm: %s", hash->hash->name)); + SILC_LOG_ERROR(("Cannot allocate algorithm: %s", + silc_hash_get_name(hash))); return FALSE; } @@ -314,7 +315,7 @@ int silc_server_protocol_ke_set_keys(SilcServer server, sock->hostname, sock->ip, idata->send_key->cipher->name, (char *)silc_hmac_get_name(idata->hmac_send), - idata->hash->hash->name, + silc_hash_get_name(idata->hash), ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : "")); return TRUE; @@ -590,7 +591,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) */ SilcSKEKeyMaterial *keymat; int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher); - int hash_len = ctx->ske->prop->hash->hash->hash_len; + int hash_len = silc_hash_len(ctx->ske->prop->hash); /* Process the key material */ keymat = silc_calloc(1, sizeof(*keymat)); @@ -1236,7 +1237,7 @@ void silc_server_protocol_rekey_generate(SilcServer server, SilcIDListData idata = (SilcIDListData)ctx->sock->user_data; SilcSKEKeyMaterial *keymat; SilcUInt32 key_len = silc_cipher_get_key_len(idata->send_key); - SilcUInt32 hash_len = idata->hash->hash->hash_len; + SilcUInt32 hash_len = silc_hash_len(idata->hash); SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)", send ? "sending" : "receiving")); @@ -1265,7 +1266,7 @@ silc_server_protocol_rekey_generate_pfs(SilcServer server, SilcIDListData idata = (SilcIDListData)ctx->sock->user_data; SilcSKEKeyMaterial *keymat; SilcUInt32 key_len = silc_cipher_get_key_len(idata->send_key); - SilcUInt32 hash_len = idata->hash->hash->hash_len; + SilcUInt32 hash_len = silc_hash_len(idata->hash); unsigned char *tmpbuf; SilcUInt32 klen; diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index 4e955a6e..e2f6454c 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -161,7 +161,7 @@ void silc_client_protocol_ke_set_keys(SilcSKE ske, conn->rekey->ske_group = silc_ske_group_get_number(group); /* Save the HASH function */ - silc_hash_alloc(hash->hash->name, &conn->hash); + silc_hash_alloc(silc_hash_get_name(hash), &conn->hash); } /* Checks the version string of the server. */ @@ -450,7 +450,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange) */ SilcSKEKeyMaterial *keymat; int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher); - int hash_len = ctx->ske->prop->hash->hash->hash_len; + int hash_len = silc_hash_len(ctx->ske->prop->hash); /* Process the key material */ keymat = silc_calloc(1, sizeof(*keymat)); @@ -792,7 +792,7 @@ silc_client_protocol_rekey_generate(SilcClient client, SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data; SilcSKEKeyMaterial *keymat; SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key); - SilcUInt32 hash_len = conn->hash->hash->hash_len; + SilcUInt32 hash_len = silc_hash_len(conn->hash); SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)", send ? "sending" : "receiving")); @@ -821,7 +821,7 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client, SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data; SilcSKEKeyMaterial *keymat; SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key); - SilcUInt32 hash_len = conn->hash->hash->hash_len; + SilcUInt32 hash_len = silc_hash_len(conn->hash); unsigned char *tmpbuf; SilcUInt32 klen; diff --git a/lib/silccrypt/DIRECTORY b/lib/silccrypt/DIRECTORY index 370ccdc2..8ed72685 100644 --- a/lib/silccrypt/DIRECTORY +++ b/lib/silccrypt/DIRECTORY @@ -4,8 +4,8 @@ @LINK=silcrng_intro.html:Introduction to SILC RNG @LINK=silcrng.html:SILC RNG Interface @LINK=silchmac.html:SILC HMAC Interface +@LINK=silchash.html:SILC Hash Interface @LINK=silccipher.html:SILC Cipher API -@LINK=silchash.html:SILC Hash API @LINK=silcpkcs.html:SILC PKCS API --> diff --git a/lib/silccrypt/sha1.c b/lib/silccrypt/sha1.c index 9c6465c6..c75be866 100644 --- a/lib/silccrypt/sha1.c +++ b/lib/silccrypt/sha1.c @@ -20,7 +20,7 @@ SILC_HASH_API_INIT(sha1) SILC_HASH_API_UPDATE(sha1) { - SHA1Update((SHA1_CTX *)context, data, len); + SHA1Update((SHA1_CTX *)context, (unsigned char *)data, len); } SILC_HASH_API_FINAL(sha1) diff --git a/lib/silccrypt/silchash.c b/lib/silccrypt/silchash.c index 5e740df5..52419b0b 100644 --- a/lib/silccrypt/silchash.c +++ b/lib/silccrypt/silchash.c @@ -24,6 +24,12 @@ #include "md5.h" #include "sha1.h" +/* The main SILC hash structure. */ +struct SilcHashStruct { + SilcHashObject *hash; + void *context; +}; + #ifndef SILC_EPOC /* List of dynamically registered hash functions. */ SilcDList silc_hash_list = NULL; @@ -159,7 +165,6 @@ bool silc_hash_alloc(const unsigned char *name, SilcHash *new_hash) *new_hash = silc_calloc(1, sizeof(**new_hash)); (*new_hash)->hash = entry; (*new_hash)->context = silc_calloc(1, entry->context_len()); - (*new_hash)->make_hash = silc_hash_make; return TRUE; } @@ -183,6 +188,20 @@ SilcUInt32 silc_hash_len(SilcHash hash) return hash->hash->hash_len; } +/* Returns the block lenght of the hash. */ + +SilcUInt32 silc_hash_block_len(SilcHash hash) +{ + return hash->hash->block_len; +} + +/* Returns the name of the hash function */ + +const char *silc_hash_get_name(SilcHash hash) +{ + return hash->hash->name; +} + /* Returns TRUE if hash algorithm `name' is supported. */ bool silc_hash_is_supported(const unsigned char *name) @@ -254,14 +273,36 @@ char *silc_hash_get_supported(void) void silc_hash_make(SilcHash hash, const unsigned char *data, SilcUInt32 len, unsigned char *return_hash) +{ + silc_hash_init(hash); + silc_hash_update(hash, data, len); + silc_hash_final(hash, return_hash); +} + +void silc_hash_init(SilcHash hash) { hash->hash->init(hash->context); - hash->hash->update(hash->context, (unsigned char *)data, len); +} + +void silc_hash_update(SilcHash hash, const unsigned char *data, + SilcUInt32 data_len) +{ + hash->hash->update(hash->context, (unsigned char *)data, data_len); +} + +void silc_hash_final(SilcHash hash, unsigned char *return_hash) +{ hash->hash->final(hash->context, return_hash); } +void silc_hash_transform(SilcHash hash, SilcUInt32 *state, + const unsigned char *data) +{ + hash->hash->transform(state, data); +} + /* Creates fingerprint of the data. If `hash' is NULL SHA1 is used as - default hash function. The returned fingerprint must be free's by the + default hash function. The returned fingerprint must be freed by the caller. */ char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data, diff --git a/lib/silccrypt/silchash.h b/lib/silccrypt/silchash.h index cf4a6be4..b076d55f 100644 --- a/lib/silccrypt/silchash.h +++ b/lib/silccrypt/silchash.h @@ -1,16 +1,15 @@ /* - silchash.h + silchash.h - Author: Pekka Riikonen + Author: Pekka Riikonen - Copyright (C) 1997 - 2001 Pekka Riikonen + Copyright (C) 1999 - 2002 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - + the Free Software Foundation; version 2 of the License. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -21,29 +20,61 @@ #ifndef SILCHASH_H #define SILCHASH_H -/* The default Silc hash object to represent any hash function in SILC. */ +/****h* silccrypt/SILC Hash Interface + * + * DESCRIPTION + * + * This is the interface for hash functions which are used to create + * message digests. The routines are used in various cryptographic + * operations. SILC Hash Interface is used for example by the + * SILC HMAC Interface (SilcHmac). + * + ***/ + +/****s* silccrypt/SilcHashAPI/SilcHash + * + * NAME + * + * typedef struct SilcHashStruct *SilcHash; + * + * DESCRIPTION + * + * This context is the actual hash function context and is allocated + * by silc_hash_alloc and given as argument usually to all + * silc_hash_* functions. It is freed by the silc_hash_free + * function. + * + ***/ +typedef struct SilcHashStruct *SilcHash; + +/****s* silccrypt/SilcHashAPI/SilcHashObject + * + * NAME + * + * typedef struct { ... } SilcHashObject; + * + * DESCRIPTION + * + * This structure represents one hash function. The hash function's + * name, digest length and block length are defined in the structure. + * This structure is then given as argument to the silc_hash_register. + * That function is used to register all hash functions into SILC. + * They can be then allocated by the name found in this structure by + * calling the silc_hash_alloc. + * + ***/ typedef struct { char *name; SilcUInt32 hash_len; SilcUInt32 block_len; void (*init)(void *); - void (*update)(void *, unsigned char *, SilcUInt32); + void (*update)(void *, const unsigned char *, SilcUInt32); void (*final)(void *, unsigned char *); - void (*transform)(SilcUInt32 *, unsigned char *); + void (*transform)(SilcUInt32 *, const unsigned char *); SilcUInt32 (*context_len)(); } SilcHashObject; -/* The main SILC hash structure. Use SilcHash instead of SilcHashStruct. - Also remember that SilcHash is a pointer. */ -typedef struct SilcHashStruct { - SilcHashObject *hash; - void *context; - - void (*make_hash)(struct SilcHashStruct *, const unsigned char *, - SilcUInt32, unsigned char *); -} *SilcHash; - /* Marks for all hash functions. This can be used in silc_hash_unregister to unregister all hash function at once. */ #define SILC_ALL_HASH_FUNCTIONS ((SilcHashObject *)1) @@ -72,30 +103,313 @@ extern DLLAPI const SilcHashObject silc_default_hash[]; /* Macros that can be used to declare SILC Hash API functions. */ #define SILC_HASH_API_INIT(hash) \ void silc_##hash##_init(void *context) -#define SILC_HASH_API_UPDATE(hash) \ -void silc_##hash##_update(void *context, unsigned char *data, \ - SilcUInt32 len) +#define SILC_HASH_API_UPDATE(hash) \ +void silc_##hash##_update(void *context, const unsigned char *data, \ + SilcUInt32 len) #define SILC_HASH_API_FINAL(hash) \ void silc_##hash##_final(void *context, unsigned char *digest) #define SILC_HASH_API_TRANSFORM(hash) \ -void silc_##hash##_transform(SilcUInt32 *state, \ - unsigned char *buffer) +void silc_##hash##_transform(SilcUInt32 *state, const unsigned char *buffer) #define SILC_HASH_API_CONTEXT_LEN(hash) \ SilcUInt32 silc_##hash##_context_len() /* Prototypes */ + +/****f* silccrypt/SilcHashAPI/silc_hash_register + * + * SYNOPSIS + * + * bool silc_hash_register(const SilcHashObject *hash); + * + * DESCRIPTION + * + * Registers a new hash function into the SILC. This function is used + * at the initialization of the SILC. All registered hash functions + * should be unregistered with silc_hash_unregister. The `hash' includes + * the name of the hash function, digest length and block length. Usually + * this function is not called directly. Instead, application can call + * the silc_hash_register_default to register all default hash functions + * that are builtin the sources. Returns FALSE on error. + * + ***/ bool silc_hash_register(const SilcHashObject *hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_unregister + * + * SYNOPSIS + * + * bool silc_hash_unregister(SilcHashObject *hash); + * + * DESCRIPTION + * + * Unregister a hash function from SILC by the SilcHashObject `hash'. + * This should be called for all registered hash functions. Returns + * FALSE on error. + * + ***/ bool silc_hash_unregister(SilcHashObject *hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_register_default + * + * SYNOPSIS + * + * bool silc_hash_register_default(void); + * + * DESCRIPTION + * + * Registers all default hash functions into the SILC. These are the + * hash functions that are builtin in the sources. See the list of + * default hash functions in the silchash.c source file. The application + * may use this to register default hash functions if specific hash + * function in any specific order is not wanted (application's + * configuration usually may decide the order of the registration, in + * which case this function should not be used). + * + ***/ bool silc_hash_register_default(void); + +/****f* silccrypt/SilcHashAPI/silc_hash_alloc + * + * SYNOPSIS + * + * bool silc_hash_alloc(const unsigned char *name, SilcHash *new_hash); + * + * DESCRIPTION + * + * Allocates a new SilcHash object of name of `name'. The new allocated + * hash function is returned into `new_hash' pointer. This function + * returns FALSE if such hash function does not exist. + * + ***/ bool silc_hash_alloc(const unsigned char *name, SilcHash *new_hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_free + * + * SYNOPSIS + * + * void silc_hash_free(SilcHash hash); + * + * DESCRIPTION + * + * Frees the allocated hash function context. + * + ***/ void silc_hash_free(SilcHash hash); -SilcUInt32 silc_hash_len(SilcHash hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_is_supported + * + * SYNOPSIS + * + * bool silc_hash_is_supported(const unsigned char *name); + * + * DESCRIPTION + * + * Returns TRUE if the hash function indicated by the `name' exists. + * + ***/ bool silc_hash_is_supported(const unsigned char *name); + +/****f* silccrypt/SilcHashAPI/silc_hash_get_supported + * + * SYNOPSIS + * + * char *silc_hash_get_supported(void); + * + * DESCRIPTION + * + * Returns comma (`,') separated list of registered hash functions This + * is used for example when sending supported hash function list during + * the SILC Key Exchange protocol (SKE). The caller must free the returned + * pointer. + * + ***/ char *silc_hash_get_supported(void); + +/****f* silccrypt/SilcHashAPI/silc_hash_len + * + * SYNOPSIS + * + * SilcUInt32 silc_hash_len(SilcHash hash); + * + * DESCRIPTION + * + * Returns the length of the message digest the hash function produce. + * + ***/ +SilcUInt32 silc_hash_len(SilcHash hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_block_len + * + * SYNOPSIS + * + * SilcUInt32 silc_hash_block_len(SilcHash hash); + * + * DESCRIPTION + * + * Returns the block length of the hash function. + * + ***/ +SilcUInt32 silc_hash_block_len(SilcHash hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_get_name + * + * SYNOPSIS + * + * const char *silc_hash_get_name(SilcHash hash); + * + * DESCRIPTION + * + * Returns the name of the hash function indicated by the `hash' context. + * + ***/ +const char *silc_hash_get_name(SilcHash hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_make + * + * SYNOPSIS + * + * void silc_hash_make(SilcHash hash, const unsigned char *data, + * SilcUInt32 len, unsigned char *return_hash); + * + * DESCRIPTION + * + * Computes the message digest (hash) out of the data indicated by + * `data' of length of `len' bytes. Returns the message digest to the + * `return_hash' buffer which must be at least of the size of the + * message digest the `hash' produces. + * + ***/ void silc_hash_make(SilcHash hash, const unsigned char *data, SilcUInt32 len, unsigned char *return_hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_init + * + * SYNOPSIS + * + * void silc_hash_init(SilcHash hash); + * + * DESCRIPTION + * + * Sometimes calling the silc_hash_make might not be the most optimal + * case of computing digests. If you have a lot of different data + * that you need to put together for computing a digest you may either + * put them into a buffer and compute the digest from the buffer by + * calling the silc_hash_make, or you can use the silc_hash_init, + * silc_hash_update and silc_hash_final to do the digest. This function + * prepares the allocated hash function context for this kind of digest + * computation. To add the data to be used in the digest computation + * call the silc_hash_update function. + * + ***/ +void silc_hash_init(SilcHash hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_update + * + * SYNOPSIS + * + * void silc_hash_update(SilcHash hash, const unsigned char *data, + * SilcUInt32 data_len); + * + * DESCRIPTION + * + * This function may be called to add data to be used in the digest + * computation. This can be called multiple times to add data from + * many sources before actually computing the digest. Once you've + * added all the data you need you can call the silc_hash_final to + * actually produce the message digest value. + * + * EXAMPLE + * + * unsigned char digest[20]; + * + * silc_hash_init(hash); + * silc_hash_update(hash, data, data_len); + * silc_hash_update(hash, more_data, more_data_len); + * silc_hash_final(hash, digest); + * + ***/ +void silc_hash_update(SilcHash hash, const unsigned char *data, + SilcUInt32 data_len); + +/****f* silccrypt/SilcHashAPI/silc_hash_final + * + * SYNOPSIS + * + * void silc_hash_final(SilcHash hash, unsigned char *return_hash); + * + * DESCRIPTION + * + * This function is used to produce the final message digest from + * the data that has been added to the hash function context by calling + * the silc_hash_update function. The digest is copied in to the + * `return_hash' pointer which must be at least the size that + * the silc_hash_len returns. + * + ***/ +void silc_hash_final(SilcHash hash, unsigned char *return_hash); + +/****f* silccrypt/SilcHashAPI/silc_hash_transform + * + * SYNOPSIS + * + * void silc_hash_transform(SilcHash hash, SilcUInt32 *state, + * const unsigned char *data); + * + * DESCRIPTION + * + * This is special function for calling the hash function's internal + * digest generation function. The size of the `state' array and the + * sizeof the `data' buffer is hash function specific and must be + * known by the caller. Usually this function is not needed. + * + ***/ +void silc_hash_transform(SilcHash hash, SilcUInt32 *state, + const unsigned char *data); + +/****f* silccrypt/SilcHashAPI/silc_hash_fingerprint + * + * SYNOPSIS + * + * char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data, + * SilcUInt32 data_len); + * + * DESCRIPTION + * + * Utility function which can be used to create a textual fingerprint + * out of the data indicated by `data' of length of `data_len' bytes. + * If `hash' is NULL then SHA1 hash function is used automatically. + * The caller must free the returned string. + * + * Example output could be: + * 41BF 5C2E 4149 039A 3917 831F 65C4 0A69 F98B 0A4D + * + ***/ char *silc_hash_fingerprint(SilcHash hash, const unsigned char *data, SilcUInt32 data_len); + +/****f* silccrypt/SilcHashAPI/silc_hash_babbleprint + * + * SYNOPSIS + * + * char *silc_hash_babbleprint(SilcHash hash, const unsigned char *data, + * SilcUInt32 data_len); + * + * DESCRIPTION + * + * Utility function which can be used to create a textual bableprint + * out of the data indicated by `data' of length of `data_len' bytes. + * If `hash' is NULL then SHA1 hash function is used automatically. + * The caller must free the returned string. + * + * The babbleprint is same as fingerprint but encoded in a form which + * makes it easier to pronounce. When verifying fingerprint for example + * over a phone call, the babbleprint makes it easier to read the + * fingerprint. + * + * Example output could be: + * xiber-zulad-vubug-noban-puvyc-labac-zonos-gedik-novem-rudog-tyxix + * + ***/ char *silc_hash_babbleprint(SilcHash hash, const unsigned char *data, SilcUInt32 data_len); diff --git a/lib/silccrypt/silchmac.c b/lib/silccrypt/silchmac.c index dfde14da..970cc600 100644 --- a/lib/silccrypt/silchmac.c +++ b/lib/silccrypt/silchmac.c @@ -24,14 +24,13 @@ 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 @@ -54,18 +53,21 @@ static void silc_hmac_init_internal(SilcHmac hmac, unsigned char *key, 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 */ @@ -73,7 +75,7 @@ static void silc_hmac_init_internal(SilcHmac hmac, unsigned char *key, 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; } @@ -234,7 +236,6 @@ void silc_hmac_free(SilcHmac hmac) silc_free(hmac->key); } - silc_free(hmac->hash_context); silc_free(hmac); } } @@ -408,15 +409,9 @@ void silc_hmac_init_with_key(SilcHmac hmac, const unsigned char *key, 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_hash_init(hash); + silc_hash_update(hash, hmac->inner_pad, silc_hash_block_len(hash)); } /* Add data to be used in the MAC computation. */ @@ -425,7 +420,7 @@ void silc_hmac_update(SilcHmac hmac, const unsigned char *data, 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. */ @@ -436,12 +431,11 @@ void silc_hmac_final(SilcHmac hmac, unsigned char *return_hash, 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)); diff --git a/lib/silccrypt/silchmac.h b/lib/silccrypt/silchmac.h index ae9ab2e3..c9b3bed0 100644 --- a/lib/silccrypt/silchmac.h +++ b/lib/silccrypt/silchmac.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1999 - 2001 Pekka Riikonen + Copyright (C) 1999 - 2002 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 diff --git a/lib/silccrypt/silcpkcs.c b/lib/silccrypt/silcpkcs.c index 8aa9d516..0a5bd31b 100644 --- a/lib/silccrypt/silcpkcs.c +++ b/lib/silccrypt/silcpkcs.c @@ -361,7 +361,7 @@ int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash, int ret; silc_hash_make(hash, src, src_len, hashr); - hash_len = hash->hash->hash_len; + hash_len = silc_hash_len(hash); SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len); @@ -385,7 +385,7 @@ int silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash, int ret; silc_hash_make(hash, data, data_len, hashr); - hash_len = hash->hash->hash_len; + hash_len = silc_hash_len(hash); SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len); diff --git a/lib/silccrypt/silcrng.c b/lib/silccrypt/silcrng.c index 3d7b031a..4fa86fa4 100644 --- a/lib/silccrypt/silcrng.c +++ b/lib/silccrypt/silcrng.c @@ -399,7 +399,7 @@ static void silc_rng_stir_pool(SilcRng rng) /* First CFB pass */ for (i = 0; i < SILC_RNG_POOLSIZE; i += 5) { - rng->sha1->hash->transform(iv, rng->key); + silc_hash_transform(rng->sha1, iv, rng->key); iv[0] = rng->pool[i] ^= iv[0]; iv[1] = rng->pool[i + 1] ^= iv[1]; iv[2] = rng->pool[i + 2] ^= iv[2]; @@ -412,7 +412,7 @@ static void silc_rng_stir_pool(SilcRng rng) /* Second CFB pass */ for (i = 0; i < SILC_RNG_POOLSIZE; i += 5) { - rng->sha1->hash->transform(iv, rng->key); + silc_hash_transform(rng->sha1, iv, rng->key); iv[0] = rng->pool[i] ^= iv[0]; iv[1] = rng->pool[i + 1] ^= iv[1]; iv[2] = rng->pool[i + 2] ^= iv[2]; diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index 756d505d..5e277b83 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -1695,7 +1695,7 @@ static SilcSKEStatus silc_ske_make_hash(SilcSKE ske, /* Make the hash */ silc_hash_make(ske->prop->hash, buf->data, buf->len, return_hash); - *return_hash_len = ske->prop->hash->hash->hash_len; + *return_hash_len = silc_hash_len(ske->prop->hash); if (initiator == FALSE) { SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);