hash.c revision 74072
16458Sache/*- 26458Sache * Copyright (c) 2000 Mark R V Murray 36458Sache * All rights reserved. 46458Sache * 56458Sache * Redistribution and use in source and binary forms, with or without 66458Sache * modification, are permitted provided that the following conditions 76458Sache * are met: 86458Sache * 1. Redistributions of source code must retain the above copyright 96458Sache * notice, this list of conditions and the following disclaimer 106458Sache * in this position and unchanged. 116458Sache * 2. Redistributions in binary form must reproduce the above copyright 126458Sache * notice, this list of conditions and the following disclaimer in the 136458Sache * documentation and/or other materials provided with the distribution. 146458Sache * 156458Sache * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 168858Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 176458Sache * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 186458Sache * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 196458Sache * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 206458Sache * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 216458Sache * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 226458Sache * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 236458Sache * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 246458Sache * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 256458Sache * 266458Sache * $FreeBSD: head/sys/dev/random/hash.c 74072 2001-03-10 12:51:55Z markm $ 276458Sache */ 286458Sache 296458Sache#include <sys/param.h> 306458Sache#include <sys/systm.h> 316458Sache#include <sys/queue.h> 326458Sache#include <sys/libkern.h> 336458Sache#include <sys/random.h> 346458Sache#include <sys/types.h> 356458Sache 366458Sache#include <crypto/rijndael/rijndael.h> 376458Sache 386458Sache#include <dev/random/hash.h> 396458Sache 406458Sache/* initialise the hash by zeroing it */ 416458Sachevoid 426458Sacheyarrow_hash_init(struct yarrowhash *context) 436458Sache{ 446458Sache rijndael_cipherInit(&context->cipher, MODE_CBC, NULL); 456458Sache bzero(context->hash, KEYSIZE); 466458Sache context->partial = 0; 476458Sache} 486458Sache 496458Sache/* Do a Davies-Meyer hash using a block cipher. 506458Sache * H_0 = I 516458Sache * H_i = E_M_i(H_i-1) ^ H_i-1 526458Sache */ 536458Sachevoid 546458Sacheyarrow_hash_iterate(struct yarrowhash *context, void *data, size_t size) 556458Sache{ 5620442Sjkh u_char temp[KEYSIZE]; 576458Sache u_int i, j; 586458Sache 596458Sache for (i = 0; i < size; i++) { 606458Sache context->accum[context->partial++] = ((u_char *)(data))[i]; 616458Sache if (context->partial == (KEYSIZE - 1)) { 626458Sache rijndael_makeKey(&context->hashkey, DIR_ENCRYPT, 637959Sache KEYSIZE*8, context->accum); 646458Sache rijndael_blockEncrypt(&context->cipher, 656458Sache &context->hashkey, context->hash, 666458Sache KEYSIZE*8, temp); 676458Sache for (j = 0; j < KEYSIZE; j++) 686458Sache context->hash[j] ^= temp[j]; 696458Sache bzero(context->accum, KEYSIZE); 706458Sache context->partial = 0; 716458Sache } 726458Sache } 736458Sache} 746458Sache 756458Sache/* Conclude by returning the hash in the supplied /buf/ which must be 766458Sache * KEYSIZE bytes long. Trailing data (less than KEYSIZE bytes) are 776458Sache * not forgotten. 786458Sache */ 796458Sachevoid 806458Sacheyarrow_hash_finish(struct yarrowhash *context, void *buf) 816458Sache{ 826458Sache u_char temp[KEYSIZE]; 836458Sache int i; 846458Sache 856458Sache if (context->partial) { 866458Sache rijndael_makeKey(&context->hashkey, DIR_ENCRYPT, 876458Sache KEYSIZE*8, context->accum); 886458Sache rijndael_blockEncrypt(&context->cipher, 898858Srgrimes &context->hashkey, context->hash, 906458Sache KEYSIZE*8, temp); 916458Sache for (i = 0; i < KEYSIZE; i++) 926458Sache context->hash[i] ^= temp[i]; 936458Sache } 946458Sache memcpy(buf, context->hash, KEYSIZE); 958858Srgrimes bzero(context->hash, KEYSIZE); 966458Sache} 976458Sache 986458Sache/* Initialise the encryption routine by setting up the key schedule 996458Sache * from the supplied /key/ which must be KEYSIZE bytes of binary 1007959Sache * data. 1017959Sache */ 1027959Sachevoid 1036458Sacheyarrow_encrypt_init(struct yarrowkey *context, void *data) 1046458Sache{ 1058858Srgrimes rijndael_cipherInit(&context->cipher, MODE_CBC, NULL); 1066458Sache rijndael_makeKey(&context->key, DIR_ENCRYPT, KEYSIZE*8, data); 1076458Sache} 1086458Sache 1096458Sache/* Encrypt the supplied data using the key schedule preset in the context. 1106458Sache * KEYSIZE bytes are encrypted from /d_in/ to /d_out/. 1116458Sache */ 1126458Sachevoid 1136458Sacheyarrow_encrypt(struct yarrowkey *context, void *d_in, void *d_out) 1146458Sache{ 115 rijndael_blockEncrypt(&context->cipher, &context->key, d_in, 116 KEYSIZE*8, d_out); 117} 118