~ubuntu-branches/ubuntu/trusty/rhash/trusty

« back to all changes in this revision

Viewing changes to librhash/rhash.c

  • Committer: Bazaar Package Importer
  • Author(s): Aleksey Kravchenko
  • Date: 2011-08-14 20:35:00 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110814203500-rvnovipwcpqkm91u
Tags: 1.2.7-1
* New upstream release version 1.2.7
 - Fixes security issue (Closes: #632280)
 - changed author/mantainer name to the way I prefer s/Alexey S/Aleksey/
 - simplified desriptions of binary packages
 - wriiten rules in more now standard way, using CFLAGS/LDFLAGS
 - reworded README.Debian a bit
 - aplied patch from upstream to fix possible segfault
 - aplied patch from upstream to fix glibc runtime warning
 - aplied patch from upstream to repair -openssl option handling

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
#include "hex.h"
30
30
#include "rhash.h" /* RHash library interface */
31
31
 
 
32
#define STATE_ACTIVE  0xb01dbabe
 
33
#define STATE_STOPED  0xdeadbeef
 
34
#define STATE_DELETED 0xdecea5ed
 
35
 
32
36
/**
33
37
 * Initialize static data of rhash algorithms
34
38
 */
40
44
#endif
41
45
}
42
46
 
43
 
#if 0
44
 
/**
45
 
 * Free allocated resources
46
 
 */
47
 
void rhash_library_free(void)
48
 
{
49
 
        rhash_free_algorithms();
50
 
}
51
 
#endif
52
 
 
53
47
/**
54
48
 * Returns the number of supported hash algorithms.
55
49
 *
60
54
        return rhash_info_size;
61
55
}
62
56
 
63
 
/* basic (lo-level) rhash library functions */
 
57
/* Lo-level rhash library functions */
64
58
 
65
59
/**
66
 
 * Allocate and initialize RHASH library context.
67
 
 * After Initializing one should call rhash_update/rhash_final functions.
68
 
 * The context must be later freed by calling rhash_free.
 
60
 * Allocate and initialize RHash context for calculating hash(es).
 
61
 * After initializing rhash_update()/rhash_final() functions should be used.
 
62
 * Then the context must be freed by calling rhash_free().
69
63
 *
70
64
 * @param hash_id union of bit flags, containing ids of hashes to calculate.
71
65
 * @return initialized rhash context
121
115
        /* initialize common fields of the rhash context */
122
116
        rctx->msg_size = 0;
123
117
        rctx->hash_id = hash_id;
 
118
        rctx->state = STATE_ACTIVE;
124
119
        rctx->hash_vector_size = num;
125
120
        rctx->callback = rctx->callback_data = NULL;
126
121
 
129
124
        assert(phash_ctx >= (char*)&rctx->vector[num]);
130
125
 
131
126
        /* initialize context for every hash in a loop */
132
 
        for(bit_index = tail_bit_index, id = 1 << tail_bit_index, i = 0; 
 
127
        for(bit_index = tail_bit_index, id = 1 << tail_bit_index, i = 0;
133
128
                id <= hash_id; bit_index++, id = id << 1)
134
129
        {
135
130
                /* check if a hash function with given id shall be included into rctx */
165
160
        unsigned i;
166
161
        if(!ctx) return;
167
162
        assert(ctx->hash_vector_size <= RHASH_HASH_COUNT);
 
163
        ctx->state = STATE_DELETED; /* mark memory block as being removed */
168
164
 
169
165
        /* clean the hash functions, which require additional clean up */
170
166
        for(i = 0; i < ctx->hash_vector_size; i++) {
187
183
{
188
184
        unsigned i;
189
185
        assert(ctx->hash_vector_size > 0 && ctx->hash_vector_size < RHASH_HASH_COUNT);
 
186
        ctx->state = STATE_ACTIVE; /* re-activate the structure */
190
187
 
191
188
        /* re-initialize every hash in a loop */
192
189
        for(i = 0; i < ctx->hash_vector_size; i++) {
213
210
{
214
211
        unsigned i;
215
212
        assert(ctx->hash_vector_size <= RHASH_HASH_COUNT);
 
213
        if(ctx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */
 
214
 
216
215
        ctx->msg_size += length;
217
216
 
218
217
        /* call update method for every algorithm */
250
249
}
251
250
 
252
251
/**
253
 
 * Store digest for given hash_id. 
 
252
 * Store digest for given hash_id.
254
253
 * If hash_id is zero, function stores digest for a hash with the lowest id found in the context.
255
254
 * For nonzero hash_id the context must contain it, otherwise function siliently does nothing.
256
255
 *
292
291
}
293
292
 
294
293
/**
295
 
 * Set the callback function to be called from the 
 
294
 * Set the callback function to be called from the
296
295
 * rhash_file() and rhash_file_update() functions
297
296
 * on processing every file block. The file block
298
 
 * size is set internaly by rhash and now is 8 KiB.
 
297
 * size is set internally by rhash and now is 8 KiB.
299
298
 *
300
299
 * @param ctx rhash context
301
300
 * @param callback pointer to the callback function
316
315
 * @param hash_id id of hash sum to compute
317
316
 * @param message the message to process
318
317
 * @param length message length
319
 
 * @param result buffer to recieve bynary hash string
 
318
 * @param result buffer to receive binary hash string
320
319
 * @return 0 on success, -1 on error
321
320
 */
322
321
RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result)
334
333
/**
335
334
 * Hash a file or stream. Multiple hashes can be computed.
336
335
 * First, inintialize ctx parameter with rhash_init() before calling
337
 
 * rhash_file_update(). Then use rhash_final() and rhash_print() 
 
336
 * rhash_file_update(). Then use rhash_final() and rhash_print()
338
337
 * to retrive hash values. Finaly call rhash_free() on ctx
339
338
 * to free allocated memory or call rhash_reset() to reuse ctx.
340
339
 *
348
347
        unsigned char *buffer, *pmem;
349
348
        size_t length = 0, align8;
350
349
        int res = 0;
 
350
        if(ctx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */
351
351
 
352
352
        if(ctx == NULL) {
353
353
                errno = EINVAL;
359
359
        buffer = pmem + align8;
360
360
 
361
361
        while(!feof(fd)) {
 
362
                if(ctx->state != STATE_ACTIVE) break; /* stop if canceled */
 
363
 
362
364
                length = fread(buffer, 1, block_size, fd);
363
365
                /* read can return -1 on error */
364
366
                if(length == (size_t)-1) {
488
490
RHASH_API int rhash_get_hash_length(unsigned hash_id)
489
491
{
490
492
        rhash_info* info = rhash_info_by_id(hash_id);
491
 
        return (int)(info ? (info->flags & F_BS32 ? 
 
493
        return (int)(info ? (info->flags & F_BS32 ?
492
494
                BASE32_LENGTH(info->digest_size) : info->digest_size * 2) : 0);
493
495
}
494
496
 
512
514
 * @param output a buffer to print the hash to
513
515
 * @param context algorithms state
514
516
 * @param hash_id id of the sum to print
515
 
 * @param flags  controls how to print the sum, can contain flags 
 
517
 * @param flags  controls how to print the sum, can contain flags
516
518
 *               RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, e.t.c.
517
519
 * @return number of writen characters on success, 0 on fail
518
520
 */
552
554
 * @param context algorithms state
553
555
 * @param hash_id id of the hash sum to print or 0 to print the first hash
554
556
 *                saved in the context.
555
 
 * @param flags  controls how to print the sum, can contain flags 
 
557
 * @param flags  controls how to print the sum, can contain flags
556
558
 *               RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, e.t.c.
557
559
 * @return number of writen characters on success, 0 on fail
558
560
 */
613
615
#endif
614
616
 
615
617
/**
616
 
 * Process a bittorent-related rhash message.
 
618
 * Process a BitTorrent-related rhash message.
617
619
 *
618
620
 * @param msg_id message identifier
619
 
 * @param bt bittorent context
 
621
 * @param bt BitTorrent context
620
622
 * @param ldata data depending on message
621
623
 * @param rdata data depending on message
622
624
 * @return message-specific data
649
651
        return 0;
650
652
}
651
653
 
 
654
#define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0))
 
655
 
652
656
/**
653
657
 * Process a rhash message.
654
658
 *
660
664
 */
661
665
RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata)
662
666
{
663
 
#define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0))
 
667
        rhash ctx = (rhash)dst; /* for messages working with rhash context */
664
668
 
665
669
        switch(msg_id) {
666
670
        case RMSG_GET_CONTEXT:
667
671
                {
668
 
                        rhash ctx = (rhash)dst;
669
672
                        unsigned i;
670
673
                        for(i = 0; i < ctx->hash_vector_size; i++) {
671
674
                                struct rhash_hash_info* info = ctx->vector[i].hash_info;
675
678
                        return (rhash_uptr_t)0;
676
679
                }
677
680
 
 
681
        case RMSG_CANCEL:
 
682
                /* mark rhash context as canceled, in a multithreaded program */
 
683
                atomic_compare_and_swap(&ctx->state, STATE_ACTIVE, STATE_STOPED);
 
684
                return 0;
 
685
 
 
686
        case RMSG_IS_CANCELED:
 
687
                return (ctx->state == STATE_STOPED);
 
688
 
678
689
                /* openssl related messages */
679
690
#ifdef USE_OPENSSL
680
691
        case RMSG_SET_OPENSSL_MASK: