static void rmd160_final( void *context ) { RMD160_CONTEXT *hd = context; u32 t, msb, lsb; byte *p; unsigned int burn; _gcry_md_block_write(hd, NULL, 0); /* flush */; t = hd->bctx.nblocks; /* multiply by 64 to make a byte count */ lsb = t << 6; msb = t >> 26; /* add the count */ t = lsb; if( (lsb += hd->bctx.count) < t ) msb++; /* multiply by 8 to make a bit count */ t = lsb; lsb <<= 3; msb <<= 3; msb |= t >> 29; if( hd->bctx.count < 56 ) /* enough room */ { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ while( hd->bctx.count < 56 ) hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else /* need one extra block */ { hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ while( hd->bctx.count < 64 ) hd->bctx.buf[hd->bctx.count++] = 0; _gcry_md_block_write(hd, NULL, 0); /* flush */; memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */ } /* append the 64 bit count */ buf_put_le32(hd->bctx.buf + 56, lsb); buf_put_le32(hd->bctx.buf + 60, msb); burn = transform( hd, hd->bctx.buf ); _gcry_burn_stack (burn); p = hd->bctx.buf; #define X(a) do { *(u32*)p = le_bswap32(hd->h##a) ; p += 4; } while(0) X(0); X(1); X(2); X(3); X(4); #undef X }
/**************** * Shortcut functions which puts the hash value of the supplied buffer * into outbuf which must have a size of 20 bytes. */ void _gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length ) { RMD160_CONTEXT hd; _gcry_rmd160_init ( &hd ); _gcry_md_block_write ( &hd, buffer, length ); rmd160_final ( &hd ); memcpy ( outbuf, hd.bctx.buf, 20 ); }
static void md2_final (void *context) { MD2_CONTEXT *hd = context; unsigned int burn; _gcry_md_block_write(hd, NULL, 0); /* flush */; /* pad */ memset (hd->bctx.buf + hd->bctx.count, 16 - hd->bctx.count, 16 - hd->bctx.count); burn = transform_blk (hd, hd->bctx.buf); permute (hd->X, hd->C); }
/* Common function to write a chunk of data to the transform function of a hash algorithm. Note that the use of the term "block" does not imply a fixed size block. Note that we explicitly allow to use this function after the context has been finalized; the result does not have any meaning but writing after finalize is sometimes helpful to mitigate timing attacks. */ void _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen) { const unsigned char *inbuf = inbuf_arg; gcry_md_block_ctx_t *hd = context; unsigned int stack_burn = 0; const unsigned int blocksize = hd->blocksize; size_t inblocks; if (sizeof(hd->buf) < blocksize) BUG(); if (!hd->bwrite) return; if (hd->count == blocksize) /* Flush the buffer. */ { stack_burn = hd->bwrite (hd, hd->buf, 1); _gcry_burn_stack (stack_burn); stack_burn = 0; hd->count = 0; if (!++hd->nblocks) hd->nblocks_high++; } if (!inbuf) return; if (hd->count) { for (; inlen && hd->count < blocksize; inlen--) hd->buf[hd->count++] = *inbuf++; _gcry_md_block_write (hd, NULL, 0); if (!inlen) return; } if (inlen >= blocksize) { inblocks = inlen / blocksize; stack_burn = hd->bwrite (hd, inbuf, inblocks); hd->count = 0; hd->nblocks_high += (hd->nblocks + inblocks < inblocks); hd->nblocks += inblocks; inlen -= inblocks * blocksize; inbuf += inblocks * blocksize; } _gcry_burn_stack (stack_burn); for (; inlen && hd->count < blocksize; inlen--) hd->buf[hd->count++] = *inbuf++; }
/* Common function to write a chunk of data to the transform function of a hash algorithm. Note that the use of the term "block" does not imply a fixed size block. */ void _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen) { const unsigned char *inbuf = inbuf_arg; gcry_md_block_ctx_t *hd = context; unsigned int stack_burn = 0; if (sizeof(hd->buf) < hd->blocksize) BUG(); if (hd->buf == NULL || hd->bwrite == NULL) return; if (hd->count == hd->blocksize) /* Flush the buffer. */ { stack_burn = hd->bwrite (hd, hd->buf); _gcry_burn_stack (stack_burn); stack_burn = 0; hd->count = 0; if (!++hd->nblocks) hd->nblocks_high++; } if (!inbuf) return; if (hd->count) { for (; inlen && hd->count < hd->blocksize; inlen--) hd->buf[hd->count++] = *inbuf++; _gcry_md_block_write (hd, NULL, 0); if (!inlen) return; } while (inlen >= hd->blocksize) { stack_burn = hd->bwrite (hd, inbuf); hd->count = 0; if (!++hd->nblocks) hd->nblocks_high++; inlen -= hd->blocksize; inbuf += hd->blocksize; } _gcry_burn_stack (stack_burn); for (; inlen && hd->count < hd->blocksize; inlen--) hd->buf[hd->count++] = *inbuf++; }