hash.c revision 67112
156918Sru/*- 256918Sru * Copyright (c) 2000 Mark R V Murray 353451Speter * All rights reserved. 456918Sru * 553475Sobrien * Redistribution and use in source and binary forms, with or without 653475Sobrien * modification, are permitted provided that the following conditions 756918Sru * are met: 856918Sru * 1. Redistributions of source code must retain the above copyright 956918Sru * notice, this list of conditions and the following disclaimer 1056918Sru * in this position and unchanged. 1153475Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1256918Sru * notice, this list of conditions and the following disclaimer in the 1356918Sru * documentation and/or other materials provided with the distribution. 1456918Sru * 1556918Sru * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1653451Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1756918Sru * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1856918Sru * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1956918Sru * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2056918Sru * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2153451Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2253475Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2353475Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2453475Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2553475Sobrien * 2653451Speter * $FreeBSD: head/sys/dev/random/hash.c 67112 2000-10-14 10:59:56Z markm $ 2753451Speter */ 2853475Sobrien 2953475Sobrien#include <sys/param.h> 3053475Sobrien#include <sys/systm.h> 3153475Sobrien#include <sys/queue.h> 3253451Speter#include <sys/libkern.h> 3353451Speter#include <sys/random.h> 3453475Sobrien#include <sys/time.h> 3553475Sobrien#include <sys/types.h> 3653475Sobrien#include <crypto/blowfish/blowfish.h> 3753451Speter 3853451Speter#include <dev/random/hash.h> 3953475Sobrien 4053475Sobrien/* initialise the hash by copying in some supplied data */ 4153451Spetervoid 4253475Sobrienyarrow_hash_init(struct yarrowhash *context, void *data, size_t size) 4353475Sobrien{ 4453475Sobrien size_t count; 4553475Sobrien 4653475Sobrien count = size > KEYSIZE ? KEYSIZE : size; 4753475Sobrien memset(context->hash, 0xff, KEYSIZE); 4853475Sobrien memcpy(context->hash, data, count); 4953451Speter} 5053451Speter 5153475Sobrien/* Do a Davies-Meyer hash using a block cipher. 5253475Sobrien * H_0 = I 5353475Sobrien * H_i = E_M_i(H_i-1) ^ H_i-1 5453475Sobrien */ 5553451Spetervoid 5653451Speteryarrow_hash_iterate(struct yarrowhash *context, void *data, size_t size) 5753451Speter{ 5853451Speter u_char keybuffer[KEYSIZE], temp[KEYSIZE]; 5953451Speter size_t count; 6053451Speter int iteration, last, i; 6153451Speter 6253451Speter iteration = 0; 6353475Sobrien last = 0; 6453451Speter for (;;) { 6553451Speter if (size <= KEYSIZE) 6653451Speter last = 1; 6753451Speter count = size > KEYSIZE ? KEYSIZE : size; 6853451Speter memcpy(keybuffer, &((u_char *)data)[iteration], count); 6953451Speter memset(&keybuffer[KEYSIZE - count], 0xff, count); 7053451Speter BF_set_key(&context->hashkey, count, 7153451Speter &((u_char *)data)[iteration]); 7253451Speter BF_cbc_encrypt(context->hash, temp, KEYSIZE, &context->hashkey, 7353451Speter context->ivec, BF_ENCRYPT); 7453451Speter for (i = 0; i < KEYSIZE; i++) 7553451Speter context->hash[i] ^= temp[i]; 7653451Speter if (last) 7753451Speter break; 7853475Sobrien iteration += KEYSIZE; 7953475Sobrien size -= KEYSIZE; 8053475Sobrien } 8156918Sru} 8256918Sru 8356918Sru/* Conclude by returning a pointer to the data */ 8453475Sobrienvoid 8553475Sobrienyarrow_hash_finish(struct yarrowhash *context, void *buf) 8653475Sobrien{ 8753475Sobrien memcpy(buf, context->hash, sizeof(context->hash)); 8853475Sobrien} 8953475Sobrien 9053475Sobrien/* Initialise the encryption routine by setting up the key schedule */ 9153475Sobrienvoid 9253475Sobrienyarrow_encrypt_init(struct yarrowkey *context, void *data, size_t size) 9353475Sobrien{ 9453475Sobrien size_t count; 9553475Sobrien 9653475Sobrien count = size > KEYSIZE ? KEYSIZE : size; 9753475Sobrien BF_set_key(&context->key, size, data); 9853475Sobrien} 9953475Sobrien 10053475Sobrien/* Encrypt the supplied data using the key schedule preset in the context */ 10153475Sobrienvoid 10253451Speteryarrow_encrypt(struct yarrowkey *context, void *d_in, void *d_out, size_t size) 10353451Speter{ 10453451Speter size_t count; 10553451Speter int iteration, last; 10653451Speter 10753451Speter last = 0; 10853451Speter for (iteration = 0;; iteration += KEYSIZE) { 10953451Speter if (size <= KEYSIZE) 11053451Speter last = 1; 11153451Speter count = size > KEYSIZE ? KEYSIZE : size; 11253451Speter BF_cbc_encrypt(&((u_char *)d_in)[iteration], 11353475Sobrien &((u_char *)d_out)[iteration], count, &context->key, 11453451Speter context->ivec, BF_ENCRYPT); 11553451Speter if (last) 11653451Speter break; 11753475Sobrien size -= KEYSIZE; 11853451Speter } 11953451Speter} 12053451Speter