sha0c.c revision 92913
144290Swollman/* crypto/sha/sha_dgst.c */ 244290Swollman/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 344290Swollman * All rights reserved. 444290Swollman * 544290Swollman * This package is an SSL implementation written 644290Swollman * by Eric Young (eay@cryptsoft.com). 744290Swollman * The implementation was written so as to conform with Netscapes SSL. 844290Swollman * 944290Swollman * This library is free for commercial and non-commercial use as long as 1044290Swollman * the following conditions are aheared to. The following conditions 1144290Swollman * apply to all code found in this distribution, be it the RC4, RSA, 1244290Swollman * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1344290Swollman * included with this distribution is covered by the same copyright terms 1444290Swollman * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1544290Swollman * 1644290Swollman * Copyright remains Eric Young's, and as such any Copyright notices in 1744290Swollman * the code are not to be removed. 1844290Swollman * If this package is used in a product, Eric Young should be given attribution 1944290Swollman * as the author of the parts of the library used. 2044290Swollman * This can be in the form of a textual message at program startup or 2144290Swollman * in documentation (online or textual) provided with the package. 2244290Swollman * 2344290Swollman * Redistribution and use in source and binary forms, with or without 2444290Swollman * modification, are permitted provided that the following conditions 2544290Swollman * are met: 2644290Swollman * 1. Redistributions of source code must retain the copyright 2744290Swollman * notice, this list of conditions and the following disclaimer. 2844290Swollman * 2. Redistributions in binary form must reproduce the above copyright 2944290Swollman * notice, this list of conditions and the following disclaimer in the 3044290Swollman * documentation and/or other materials provided with the distribution. 3144290Swollman * 3. All advertising materials mentioning features or use of this software 3244290Swollman * must display the following acknowledgement: 3344290Swollman * "This product includes cryptographic software written by 3444290Swollman * Eric Young (eay@cryptsoft.com)" 3544290Swollman * The word 'cryptographic' can be left out if the rouines from the library 3644290Swollman * being used are not cryptographic related :-). 3744290Swollman * 4. If you include any Windows specific code (or a derivative thereof) from 3844290Swollman * the apps directory (application code) you must include an acknowledgement: 3944290Swollman * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4044290Swollman * 4144290Swollman * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4244290Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4344290Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4444290Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4544290Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4644290Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4744290Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4844290Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4944290Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5044290Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5144290Swollman * SUCH DAMAGE. 5244290Swollman * 5344290Swollman * The licence and distribution terms for any publically available version or 5444290Swollman * derivative of this code cannot be changed. i.e. this code cannot simply be 5544290Swollman * copied and put under another distribution licence 5644290Swollman * [including the GNU Public Licence.] 5744290Swollman */ 5844290Swollman 5984211Sdillon#include <sys/cdefs.h> 6084211Sdillon__FBSDID("$FreeBSD: head/lib/libmd/sha0c.c 92913 2002-03-21 23:39:28Z obrien $"); 6184211Sdillon 6244290Swollman#include <sys/types.h> 6344290Swollman 6444290Swollman#include <stdio.h> 6544290Swollman#include <string.h> 6644290Swollman 6744290Swollman#if 0 6844290Swollman#include <machine/ansi.h> /* we use the __ variants of bit-sized types */ 6944290Swollman#endif 7044290Swollman#include <machine/endian.h> 7144290Swollman 7244290Swollman#define SHA_0 7344290Swollman#undef SHA_1 7444290Swollman#include "sha.h" 7544290Swollman#include "sha_locl.h" 7644290Swollman 7744290Swollmanchar *SHA_version="SHA part of SSLeay 0.9.0b 11-Oct-1998"; 7844290Swollman 7944290Swollman/* Implemented from SHA-0 document - The Secure Hash Algorithm 8044290Swollman */ 8144290Swollman 8244290Swollman#define INIT_DATA_h0 (unsigned long)0x67452301L 8344290Swollman#define INIT_DATA_h1 (unsigned long)0xefcdab89L 8444290Swollman#define INIT_DATA_h2 (unsigned long)0x98badcfeL 8544290Swollman#define INIT_DATA_h3 (unsigned long)0x10325476L 8644290Swollman#define INIT_DATA_h4 (unsigned long)0xc3d2e1f0L 8744290Swollman 8844290Swollman#define K_00_19 0x5a827999L 8944290Swollman#define K_20_39 0x6ed9eba1L 9044290Swollman#define K_40_59 0x8f1bbcdcL 9144290Swollman#define K_60_79 0xca62c1d6L 9244290Swollman 9344290Swollman#ifndef NOPROTO 9444290Swollman void sha_block(SHA_CTX *c, const u_int32_t *p, int num); 9544290Swollman#else 9644290Swollman void sha_block(); 9744290Swollman#endif 9844290Swollman 9944290Swollman#define M_c2nl c2nl 10044290Swollman#define M_p_c2nl p_c2nl 10144290Swollman#define M_c2nl_p c2nl_p 10244290Swollman#define M_p_c2nl_p p_c2nl_p 10344290Swollman#define M_nl2c nl2c 10444290Swollman 10544290Swollmanvoid SHA_Init(c) 10644290SwollmanSHA_CTX *c; 10744290Swollman { 10844290Swollman c->h0=INIT_DATA_h0; 10944290Swollman c->h1=INIT_DATA_h1; 11044290Swollman c->h2=INIT_DATA_h2; 11144290Swollman c->h3=INIT_DATA_h3; 11244290Swollman c->h4=INIT_DATA_h4; 11344290Swollman c->Nl=0; 11444290Swollman c->Nh=0; 11544290Swollman c->num=0; 11644290Swollman } 11744290Swollman 11844290Swollmanvoid SHA_Update(c, data, len) 11944290SwollmanSHA_CTX *c; 12044290Swollmanconst unsigned char *data; 12144304Swollmansize_t len; 12244290Swollman { 12392913Sobrien u_int32_t *p; 12444290Swollman int ew,ec,sw,sc; 12544290Swollman u_int32_t l; 12644290Swollman 12744290Swollman if (len == 0) return; 12844290Swollman 12944290Swollman l=(c->Nl+(len<<3))&0xffffffffL; 13044290Swollman if (l < c->Nl) /* overflow */ 13144290Swollman c->Nh++; 13244290Swollman c->Nh+=(len>>29); 13344290Swollman c->Nl=l; 13444290Swollman 13544290Swollman if (c->num != 0) 13644290Swollman { 13744290Swollman p=c->data; 13844290Swollman sw=c->num>>2; 13944290Swollman sc=c->num&0x03; 14044290Swollman 14144290Swollman if ((c->num+len) >= SHA_CBLOCK) 14244290Swollman { 14344290Swollman l= p[sw]; 14444290Swollman M_p_c2nl(data,l,sc); 14544290Swollman p[sw++]=l; 14644290Swollman for (; sw<SHA_LBLOCK; sw++) 14744290Swollman { 14844290Swollman M_c2nl(data,l); 14944290Swollman p[sw]=l; 15044290Swollman } 15144290Swollman len-=(SHA_CBLOCK-c->num); 15244290Swollman 15344290Swollman sha_block(c,p,64); 15444290Swollman c->num=0; 15544290Swollman /* drop through and do the rest */ 15644290Swollman } 15744290Swollman else 15844290Swollman { 15944290Swollman c->num+=(int)len; 16044290Swollman if ((sc+len) < 4) /* ugly, add char's to a word */ 16144290Swollman { 16244290Swollman l= p[sw]; 16344290Swollman M_p_c2nl_p(data,l,sc,len); 16444290Swollman p[sw]=l; 16544290Swollman } 16644290Swollman else 16744290Swollman { 16844290Swollman ew=(c->num>>2); 16944290Swollman ec=(c->num&0x03); 17044290Swollman l= p[sw]; 17144290Swollman M_p_c2nl(data,l,sc); 17244290Swollman p[sw++]=l; 17344290Swollman for (; sw < ew; sw++) 17444290Swollman { M_c2nl(data,l); p[sw]=l; } 17544290Swollman if (ec) 17644290Swollman { 17744290Swollman M_c2nl_p(data,l,ec); 17844290Swollman p[sw]=l; 17944290Swollman } 18044290Swollman } 18144290Swollman return; 18244290Swollman } 18344290Swollman } 18444290Swollman /* We can only do the following code for assember, the reason 18544290Swollman * being that the sha_block 'C' version changes the values 18644290Swollman * in the 'data' array. The assember code avoids this and 18744290Swollman * copies it to a local array. I should be able to do this for 18844290Swollman * the C version as well.... 18944290Swollman */ 19044290Swollman#if 1 19144290Swollman#if BYTE_ORDER == BIG_ENDIAN || defined(SHA_ASM) 19244290Swollman if ((((unsigned int)data)%sizeof(u_int32_t)) == 0) 19344290Swollman { 19444290Swollman sw=len/SHA_CBLOCK; 19544290Swollman if (sw) 19644290Swollman { 19744290Swollman sw*=SHA_CBLOCK; 19844290Swollman sha_block(c,(u_int32_t *)data,sw); 19944290Swollman data+=sw; 20044290Swollman len-=sw; 20144290Swollman } 20244290Swollman } 20344290Swollman#endif 20444290Swollman#endif 20544290Swollman /* we now can process the input data in blocks of SHA_CBLOCK 20644290Swollman * chars and save the leftovers to c->data. */ 20744290Swollman p=c->data; 20844290Swollman while (len >= SHA_CBLOCK) 20944290Swollman { 21044290Swollman#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN 21144290Swollman if (p != (u_int32_t *)data) 21244290Swollman memcpy(p,data,SHA_CBLOCK); 21344290Swollman data+=SHA_CBLOCK; 21444290Swollman# if BYTE_ORDER == LITTLE_ENDIAN 21544290Swollman# ifndef SHA_ASM /* Will not happen */ 21644290Swollman for (sw=(SHA_LBLOCK/4); sw; sw--) 21744290Swollman { 21844290Swollman Endian_Reverse32(p[0]); 21944290Swollman Endian_Reverse32(p[1]); 22044290Swollman Endian_Reverse32(p[2]); 22144290Swollman Endian_Reverse32(p[3]); 22244290Swollman p+=4; 22344290Swollman } 22444290Swollman p=c->data; 22544290Swollman# endif 22644290Swollman# endif 22744290Swollman#else 22844290Swollman for (sw=(SHA_BLOCK/4); sw; sw--) 22944290Swollman { 23044290Swollman M_c2nl(data,l); *(p++)=l; 23144290Swollman M_c2nl(data,l); *(p++)=l; 23244290Swollman M_c2nl(data,l); *(p++)=l; 23344290Swollman M_c2nl(data,l); *(p++)=l; 23444290Swollman } 23544290Swollman p=c->data; 23644290Swollman#endif 23744290Swollman sha_block(c,p,64); 23844290Swollman len-=SHA_CBLOCK; 23944290Swollman } 24044290Swollman ec=(int)len; 24144290Swollman c->num=ec; 24244290Swollman ew=(ec>>2); 24344290Swollman ec&=0x03; 24444290Swollman 24544290Swollman for (sw=0; sw < ew; sw++) 24644290Swollman { M_c2nl(data,l); p[sw]=l; } 24744290Swollman M_c2nl_p(data,l,ec); 24844290Swollman p[sw]=l; 24944290Swollman } 25044290Swollman 25144290Swollmanvoid SHA_Transform(c,b) 25244290SwollmanSHA_CTX *c; 25344290Swollmanunsigned char *b; 25444290Swollman { 25544290Swollman u_int32_t p[16]; 25644290Swollman#if BYTE_ORDER == LITTLE_ENDIAN 25744290Swollman u_int32_t *q; 25844290Swollman int i; 25944290Swollman#endif 26044290Swollman 26144290Swollman#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN 26244290Swollman memcpy(p,b,64); 26344290Swollman#if BYTE_ORDER == LITTLE_ENDIAN 26444290Swollman q=p; 26544290Swollman for (i=(SHA_LBLOCK/4); i; i--) 26644290Swollman { 26744290Swollman Endian_Reverse32(q[0]); 26844290Swollman Endian_Reverse32(q[1]); 26944290Swollman Endian_Reverse32(q[2]); 27044290Swollman Endian_Reverse32(q[3]); 27144290Swollman q+=4; 27244290Swollman } 27344290Swollman#endif 27444290Swollman#else 27544290Swollman q=p; 27644290Swollman for (i=(SHA_LBLOCK/4); i; i--) 27744290Swollman { 27844290Swollman u_int32_t l; 27944290Swollman c2nl(b,l); *(q++)=l; 28044290Swollman c2nl(b,l); *(q++)=l; 28144290Swollman c2nl(b,l); *(q++)=l; 28244290Swollman c2nl(b,l); *(q++)=l; 28344290Swollman } 28444290Swollman#endif 28544290Swollman sha_block(c,p,64); 28644290Swollman } 28744290Swollman 28844290Swollmanvoid sha_block(c, W, num) 28944290SwollmanSHA_CTX *c; 29044290Swollmanconst u_int32_t *W; 29144290Swollmanint num; 29244290Swollman { 29392913Sobrien u_int32_t A,B,C,D,E,T; 29444290Swollman u_int32_t X[16]; 29544290Swollman 29644290Swollman A=c->h0; 29744290Swollman B=c->h1; 29844290Swollman C=c->h2; 29944290Swollman D=c->h3; 30044290Swollman E=c->h4; 30144290Swollman 30244290Swollman for (;;) 30344290Swollman { 30444290Swollman BODY_00_15( 0,A,B,C,D,E,T,W); 30544290Swollman BODY_00_15( 1,T,A,B,C,D,E,W); 30644290Swollman BODY_00_15( 2,E,T,A,B,C,D,W); 30744290Swollman BODY_00_15( 3,D,E,T,A,B,C,W); 30844290Swollman BODY_00_15( 4,C,D,E,T,A,B,W); 30944290Swollman BODY_00_15( 5,B,C,D,E,T,A,W); 31044290Swollman BODY_00_15( 6,A,B,C,D,E,T,W); 31144290Swollman BODY_00_15( 7,T,A,B,C,D,E,W); 31244290Swollman BODY_00_15( 8,E,T,A,B,C,D,W); 31344290Swollman BODY_00_15( 9,D,E,T,A,B,C,W); 31444290Swollman BODY_00_15(10,C,D,E,T,A,B,W); 31544290Swollman BODY_00_15(11,B,C,D,E,T,A,W); 31644290Swollman BODY_00_15(12,A,B,C,D,E,T,W); 31744290Swollman BODY_00_15(13,T,A,B,C,D,E,W); 31844290Swollman BODY_00_15(14,E,T,A,B,C,D,W); 31944290Swollman BODY_00_15(15,D,E,T,A,B,C,W); 32044290Swollman BODY_16_19(16,C,D,E,T,A,B,W,W,W,W); 32144290Swollman BODY_16_19(17,B,C,D,E,T,A,W,W,W,W); 32244290Swollman BODY_16_19(18,A,B,C,D,E,T,W,W,W,W); 32344290Swollman BODY_16_19(19,T,A,B,C,D,E,W,W,W,X); 32444290Swollman 32544290Swollman BODY_20_31(20,E,T,A,B,C,D,W,W,W,X); 32644290Swollman BODY_20_31(21,D,E,T,A,B,C,W,W,W,X); 32744290Swollman BODY_20_31(22,C,D,E,T,A,B,W,W,W,X); 32844290Swollman BODY_20_31(23,B,C,D,E,T,A,W,W,W,X); 32944290Swollman BODY_20_31(24,A,B,C,D,E,T,W,W,X,X); 33044290Swollman BODY_20_31(25,T,A,B,C,D,E,W,W,X,X); 33144290Swollman BODY_20_31(26,E,T,A,B,C,D,W,W,X,X); 33244290Swollman BODY_20_31(27,D,E,T,A,B,C,W,W,X,X); 33344290Swollman BODY_20_31(28,C,D,E,T,A,B,W,W,X,X); 33444290Swollman BODY_20_31(29,B,C,D,E,T,A,W,W,X,X); 33544290Swollman BODY_20_31(30,A,B,C,D,E,T,W,X,X,X); 33644290Swollman BODY_20_31(31,T,A,B,C,D,E,W,X,X,X); 33744290Swollman BODY_32_39(32,E,T,A,B,C,D,X); 33844290Swollman BODY_32_39(33,D,E,T,A,B,C,X); 33944290Swollman BODY_32_39(34,C,D,E,T,A,B,X); 34044290Swollman BODY_32_39(35,B,C,D,E,T,A,X); 34144290Swollman BODY_32_39(36,A,B,C,D,E,T,X); 34244290Swollman BODY_32_39(37,T,A,B,C,D,E,X); 34344290Swollman BODY_32_39(38,E,T,A,B,C,D,X); 34444290Swollman BODY_32_39(39,D,E,T,A,B,C,X); 34544290Swollman 34644290Swollman BODY_40_59(40,C,D,E,T,A,B,X); 34744290Swollman BODY_40_59(41,B,C,D,E,T,A,X); 34844290Swollman BODY_40_59(42,A,B,C,D,E,T,X); 34944290Swollman BODY_40_59(43,T,A,B,C,D,E,X); 35044290Swollman BODY_40_59(44,E,T,A,B,C,D,X); 35144290Swollman BODY_40_59(45,D,E,T,A,B,C,X); 35244290Swollman BODY_40_59(46,C,D,E,T,A,B,X); 35344290Swollman BODY_40_59(47,B,C,D,E,T,A,X); 35444290Swollman BODY_40_59(48,A,B,C,D,E,T,X); 35544290Swollman BODY_40_59(49,T,A,B,C,D,E,X); 35644290Swollman BODY_40_59(50,E,T,A,B,C,D,X); 35744290Swollman BODY_40_59(51,D,E,T,A,B,C,X); 35844290Swollman BODY_40_59(52,C,D,E,T,A,B,X); 35944290Swollman BODY_40_59(53,B,C,D,E,T,A,X); 36044290Swollman BODY_40_59(54,A,B,C,D,E,T,X); 36144290Swollman BODY_40_59(55,T,A,B,C,D,E,X); 36244290Swollman BODY_40_59(56,E,T,A,B,C,D,X); 36344290Swollman BODY_40_59(57,D,E,T,A,B,C,X); 36444290Swollman BODY_40_59(58,C,D,E,T,A,B,X); 36544290Swollman BODY_40_59(59,B,C,D,E,T,A,X); 36644290Swollman 36744290Swollman BODY_60_79(60,A,B,C,D,E,T,X); 36844290Swollman BODY_60_79(61,T,A,B,C,D,E,X); 36944290Swollman BODY_60_79(62,E,T,A,B,C,D,X); 37044290Swollman BODY_60_79(63,D,E,T,A,B,C,X); 37144290Swollman BODY_60_79(64,C,D,E,T,A,B,X); 37244290Swollman BODY_60_79(65,B,C,D,E,T,A,X); 37344290Swollman BODY_60_79(66,A,B,C,D,E,T,X); 37444290Swollman BODY_60_79(67,T,A,B,C,D,E,X); 37544290Swollman BODY_60_79(68,E,T,A,B,C,D,X); 37644290Swollman BODY_60_79(69,D,E,T,A,B,C,X); 37744290Swollman BODY_60_79(70,C,D,E,T,A,B,X); 37844290Swollman BODY_60_79(71,B,C,D,E,T,A,X); 37944290Swollman BODY_60_79(72,A,B,C,D,E,T,X); 38044290Swollman BODY_60_79(73,T,A,B,C,D,E,X); 38144290Swollman BODY_60_79(74,E,T,A,B,C,D,X); 38244290Swollman BODY_60_79(75,D,E,T,A,B,C,X); 38344290Swollman BODY_60_79(76,C,D,E,T,A,B,X); 38444290Swollman BODY_60_79(77,B,C,D,E,T,A,X); 38544290Swollman BODY_60_79(78,A,B,C,D,E,T,X); 38644290Swollman BODY_60_79(79,T,A,B,C,D,E,X); 38744290Swollman 38844290Swollman c->h0=(c->h0+E)&0xffffffffL; 38944290Swollman c->h1=(c->h1+T)&0xffffffffL; 39044290Swollman c->h2=(c->h2+A)&0xffffffffL; 39144290Swollman c->h3=(c->h3+B)&0xffffffffL; 39244290Swollman c->h4=(c->h4+C)&0xffffffffL; 39344290Swollman 39444290Swollman num-=64; 39544290Swollman if (num <= 0) break; 39644290Swollman 39744290Swollman A=c->h0; 39844290Swollman B=c->h1; 39944290Swollman C=c->h2; 40044290Swollman D=c->h3; 40144290Swollman E=c->h4; 40244290Swollman 40344290Swollman W+=16; 40444290Swollman } 40544290Swollman } 40644290Swollman 40744290Swollmanvoid SHA_Final(md, c) 40844290Swollmanunsigned char *md; 40944290SwollmanSHA_CTX *c; 41044290Swollman { 41192913Sobrien int i,j; 41292913Sobrien u_int32_t l; 41392913Sobrien u_int32_t *p; 41444290Swollman static unsigned char end[4]={0x80,0x00,0x00,0x00}; 41544290Swollman unsigned char *cp=end; 41644290Swollman 41744290Swollman /* c->num should definitly have room for at least one more byte. */ 41844290Swollman p=c->data; 41944290Swollman j=c->num; 42044290Swollman i=j>>2; 42144290Swollman#ifdef PURIFY 42244290Swollman if ((j&0x03) == 0) p[i]=0; 42344290Swollman#endif 42444290Swollman l=p[i]; 42544290Swollman M_p_c2nl(cp,l,j&0x03); 42644290Swollman p[i]=l; 42744290Swollman i++; 42844290Swollman /* i is the next 'undefined word' */ 42944290Swollman if (c->num >= SHA_LAST_BLOCK) 43044290Swollman { 43144290Swollman for (; i<SHA_LBLOCK; i++) 43244290Swollman p[i]=0; 43344290Swollman sha_block(c,p,64); 43444290Swollman i=0; 43544290Swollman } 43644290Swollman for (; i<(SHA_LBLOCK-2); i++) 43744290Swollman p[i]=0; 43844290Swollman p[SHA_LBLOCK-2]=c->Nh; 43944290Swollman p[SHA_LBLOCK-1]=c->Nl; 44044290Swollman sha_block(c,p,64); 44144290Swollman cp=md; 44244290Swollman l=c->h0; nl2c(l,cp); 44344290Swollman l=c->h1; nl2c(l,cp); 44444290Swollman l=c->h2; nl2c(l,cp); 44544290Swollman l=c->h3; nl2c(l,cp); 44644290Swollman l=c->h4; nl2c(l,cp); 44744290Swollman 44844290Swollman /* clear stuff, sha_block may be leaving some stuff on the stack 44944290Swollman * but I'm not worried :-) */ 45044290Swollman c->num=0; 45144290Swollman/* memset((char *)&c,0,sizeof(c));*/ 45244290Swollman } 45344290Swollman 454