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$"); 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 118154479Sphkvoid SHA_Update(c, in, len) 11944290SwollmanSHA_CTX *c; 120154479Sphkconst void *in; 12144304Swollmansize_t len; 12244290Swollman { 12392913Sobrien u_int32_t *p; 12444290Swollman int ew,ec,sw,sc; 12544290Swollman u_int32_t l; 126154479Sphk const unsigned char *data = in; 12744290Swollman 12844290Swollman if (len == 0) return; 12944290Swollman 13044290Swollman l=(c->Nl+(len<<3))&0xffffffffL; 13144290Swollman if (l < c->Nl) /* overflow */ 13244290Swollman c->Nh++; 13344290Swollman c->Nh+=(len>>29); 13444290Swollman c->Nl=l; 13544290Swollman 13644290Swollman if (c->num != 0) 13744290Swollman { 13844290Swollman p=c->data; 13944290Swollman sw=c->num>>2; 14044290Swollman sc=c->num&0x03; 14144290Swollman 14244290Swollman if ((c->num+len) >= SHA_CBLOCK) 14344290Swollman { 14444290Swollman l= p[sw]; 14544290Swollman M_p_c2nl(data,l,sc); 14644290Swollman p[sw++]=l; 14744290Swollman for (; sw<SHA_LBLOCK; sw++) 14844290Swollman { 14944290Swollman M_c2nl(data,l); 15044290Swollman p[sw]=l; 15144290Swollman } 15244290Swollman len-=(SHA_CBLOCK-c->num); 15344290Swollman 15444290Swollman sha_block(c,p,64); 15544290Swollman c->num=0; 15644290Swollman /* drop through and do the rest */ 15744290Swollman } 15844290Swollman else 15944290Swollman { 16044290Swollman c->num+=(int)len; 16144290Swollman if ((sc+len) < 4) /* ugly, add char's to a word */ 16244290Swollman { 16344290Swollman l= p[sw]; 16444290Swollman M_p_c2nl_p(data,l,sc,len); 16544290Swollman p[sw]=l; 16644290Swollman } 16744290Swollman else 16844290Swollman { 16944290Swollman ew=(c->num>>2); 17044290Swollman ec=(c->num&0x03); 17144290Swollman l= p[sw]; 17244290Swollman M_p_c2nl(data,l,sc); 17344290Swollman p[sw++]=l; 17444290Swollman for (; sw < ew; sw++) 17544290Swollman { M_c2nl(data,l); p[sw]=l; } 17644290Swollman if (ec) 17744290Swollman { 17844290Swollman M_c2nl_p(data,l,ec); 17944290Swollman p[sw]=l; 18044290Swollman } 18144290Swollman } 18244290Swollman return; 18344290Swollman } 18444290Swollman } 18544290Swollman /* We can only do the following code for assember, the reason 18644290Swollman * being that the sha_block 'C' version changes the values 18744290Swollman * in the 'data' array. The assember code avoids this and 18844290Swollman * copies it to a local array. I should be able to do this for 18944290Swollman * the C version as well.... 19044290Swollman */ 19144290Swollman#if 1 19244290Swollman#if BYTE_ORDER == BIG_ENDIAN || defined(SHA_ASM) 19344290Swollman if ((((unsigned int)data)%sizeof(u_int32_t)) == 0) 19444290Swollman { 19544290Swollman sw=len/SHA_CBLOCK; 19644290Swollman if (sw) 19744290Swollman { 19844290Swollman sw*=SHA_CBLOCK; 19944290Swollman sha_block(c,(u_int32_t *)data,sw); 20044290Swollman data+=sw; 20144290Swollman len-=sw; 20244290Swollman } 20344290Swollman } 20444290Swollman#endif 20544290Swollman#endif 20644290Swollman /* we now can process the input data in blocks of SHA_CBLOCK 20744290Swollman * chars and save the leftovers to c->data. */ 20844290Swollman p=c->data; 20944290Swollman while (len >= SHA_CBLOCK) 21044290Swollman { 21144290Swollman#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN 21244290Swollman if (p != (u_int32_t *)data) 21344290Swollman memcpy(p,data,SHA_CBLOCK); 21444290Swollman data+=SHA_CBLOCK; 21544290Swollman# if BYTE_ORDER == LITTLE_ENDIAN 21644290Swollman# ifndef SHA_ASM /* Will not happen */ 21744290Swollman for (sw=(SHA_LBLOCK/4); sw; sw--) 21844290Swollman { 21944290Swollman Endian_Reverse32(p[0]); 22044290Swollman Endian_Reverse32(p[1]); 22144290Swollman Endian_Reverse32(p[2]); 22244290Swollman Endian_Reverse32(p[3]); 22344290Swollman p+=4; 22444290Swollman } 22544290Swollman p=c->data; 22644290Swollman# endif 22744290Swollman# endif 22844290Swollman#else 22944290Swollman for (sw=(SHA_BLOCK/4); sw; sw--) 23044290Swollman { 23144290Swollman M_c2nl(data,l); *(p++)=l; 23244290Swollman M_c2nl(data,l); *(p++)=l; 23344290Swollman M_c2nl(data,l); *(p++)=l; 23444290Swollman M_c2nl(data,l); *(p++)=l; 23544290Swollman } 23644290Swollman p=c->data; 23744290Swollman#endif 23844290Swollman sha_block(c,p,64); 23944290Swollman len-=SHA_CBLOCK; 24044290Swollman } 24144290Swollman ec=(int)len; 24244290Swollman c->num=ec; 24344290Swollman ew=(ec>>2); 24444290Swollman ec&=0x03; 24544290Swollman 24644290Swollman for (sw=0; sw < ew; sw++) 24744290Swollman { M_c2nl(data,l); p[sw]=l; } 24844290Swollman M_c2nl_p(data,l,ec); 24944290Swollman p[sw]=l; 25044290Swollman } 25144290Swollman 25244290Swollmanvoid SHA_Transform(c,b) 25344290SwollmanSHA_CTX *c; 25444290Swollmanunsigned char *b; 25544290Swollman { 25644290Swollman u_int32_t p[16]; 25744290Swollman#if BYTE_ORDER == LITTLE_ENDIAN 25844290Swollman u_int32_t *q; 25944290Swollman int i; 26044290Swollman#endif 26144290Swollman 26244290Swollman#if BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN 26344290Swollman memcpy(p,b,64); 26444290Swollman#if BYTE_ORDER == LITTLE_ENDIAN 26544290Swollman q=p; 26644290Swollman for (i=(SHA_LBLOCK/4); i; i--) 26744290Swollman { 26844290Swollman Endian_Reverse32(q[0]); 26944290Swollman Endian_Reverse32(q[1]); 27044290Swollman Endian_Reverse32(q[2]); 27144290Swollman Endian_Reverse32(q[3]); 27244290Swollman q+=4; 27344290Swollman } 27444290Swollman#endif 27544290Swollman#else 27644290Swollman q=p; 27744290Swollman for (i=(SHA_LBLOCK/4); i; i--) 27844290Swollman { 27944290Swollman u_int32_t l; 28044290Swollman c2nl(b,l); *(q++)=l; 28144290Swollman c2nl(b,l); *(q++)=l; 28244290Swollman c2nl(b,l); *(q++)=l; 28344290Swollman c2nl(b,l); *(q++)=l; 28444290Swollman } 28544290Swollman#endif 28644290Swollman sha_block(c,p,64); 28744290Swollman } 28844290Swollman 28944290Swollmanvoid sha_block(c, W, num) 29044290SwollmanSHA_CTX *c; 29144290Swollmanconst u_int32_t *W; 29244290Swollmanint num; 29344290Swollman { 29492913Sobrien u_int32_t A,B,C,D,E,T; 29544290Swollman u_int32_t X[16]; 29644290Swollman 29744290Swollman A=c->h0; 29844290Swollman B=c->h1; 29944290Swollman C=c->h2; 30044290Swollman D=c->h3; 30144290Swollman E=c->h4; 30244290Swollman 30344290Swollman for (;;) 30444290Swollman { 30544290Swollman BODY_00_15( 0,A,B,C,D,E,T,W); 30644290Swollman BODY_00_15( 1,T,A,B,C,D,E,W); 30744290Swollman BODY_00_15( 2,E,T,A,B,C,D,W); 30844290Swollman BODY_00_15( 3,D,E,T,A,B,C,W); 30944290Swollman BODY_00_15( 4,C,D,E,T,A,B,W); 31044290Swollman BODY_00_15( 5,B,C,D,E,T,A,W); 31144290Swollman BODY_00_15( 6,A,B,C,D,E,T,W); 31244290Swollman BODY_00_15( 7,T,A,B,C,D,E,W); 31344290Swollman BODY_00_15( 8,E,T,A,B,C,D,W); 31444290Swollman BODY_00_15( 9,D,E,T,A,B,C,W); 31544290Swollman BODY_00_15(10,C,D,E,T,A,B,W); 31644290Swollman BODY_00_15(11,B,C,D,E,T,A,W); 31744290Swollman BODY_00_15(12,A,B,C,D,E,T,W); 31844290Swollman BODY_00_15(13,T,A,B,C,D,E,W); 31944290Swollman BODY_00_15(14,E,T,A,B,C,D,W); 32044290Swollman BODY_00_15(15,D,E,T,A,B,C,W); 32144290Swollman BODY_16_19(16,C,D,E,T,A,B,W,W,W,W); 32244290Swollman BODY_16_19(17,B,C,D,E,T,A,W,W,W,W); 32344290Swollman BODY_16_19(18,A,B,C,D,E,T,W,W,W,W); 32444290Swollman BODY_16_19(19,T,A,B,C,D,E,W,W,W,X); 32544290Swollman 32644290Swollman BODY_20_31(20,E,T,A,B,C,D,W,W,W,X); 32744290Swollman BODY_20_31(21,D,E,T,A,B,C,W,W,W,X); 32844290Swollman BODY_20_31(22,C,D,E,T,A,B,W,W,W,X); 32944290Swollman BODY_20_31(23,B,C,D,E,T,A,W,W,W,X); 33044290Swollman BODY_20_31(24,A,B,C,D,E,T,W,W,X,X); 33144290Swollman BODY_20_31(25,T,A,B,C,D,E,W,W,X,X); 33244290Swollman BODY_20_31(26,E,T,A,B,C,D,W,W,X,X); 33344290Swollman BODY_20_31(27,D,E,T,A,B,C,W,W,X,X); 33444290Swollman BODY_20_31(28,C,D,E,T,A,B,W,W,X,X); 33544290Swollman BODY_20_31(29,B,C,D,E,T,A,W,W,X,X); 33644290Swollman BODY_20_31(30,A,B,C,D,E,T,W,X,X,X); 33744290Swollman BODY_20_31(31,T,A,B,C,D,E,W,X,X,X); 33844290Swollman BODY_32_39(32,E,T,A,B,C,D,X); 33944290Swollman BODY_32_39(33,D,E,T,A,B,C,X); 34044290Swollman BODY_32_39(34,C,D,E,T,A,B,X); 34144290Swollman BODY_32_39(35,B,C,D,E,T,A,X); 34244290Swollman BODY_32_39(36,A,B,C,D,E,T,X); 34344290Swollman BODY_32_39(37,T,A,B,C,D,E,X); 34444290Swollman BODY_32_39(38,E,T,A,B,C,D,X); 34544290Swollman BODY_32_39(39,D,E,T,A,B,C,X); 34644290Swollman 34744290Swollman BODY_40_59(40,C,D,E,T,A,B,X); 34844290Swollman BODY_40_59(41,B,C,D,E,T,A,X); 34944290Swollman BODY_40_59(42,A,B,C,D,E,T,X); 35044290Swollman BODY_40_59(43,T,A,B,C,D,E,X); 35144290Swollman BODY_40_59(44,E,T,A,B,C,D,X); 35244290Swollman BODY_40_59(45,D,E,T,A,B,C,X); 35344290Swollman BODY_40_59(46,C,D,E,T,A,B,X); 35444290Swollman BODY_40_59(47,B,C,D,E,T,A,X); 35544290Swollman BODY_40_59(48,A,B,C,D,E,T,X); 35644290Swollman BODY_40_59(49,T,A,B,C,D,E,X); 35744290Swollman BODY_40_59(50,E,T,A,B,C,D,X); 35844290Swollman BODY_40_59(51,D,E,T,A,B,C,X); 35944290Swollman BODY_40_59(52,C,D,E,T,A,B,X); 36044290Swollman BODY_40_59(53,B,C,D,E,T,A,X); 36144290Swollman BODY_40_59(54,A,B,C,D,E,T,X); 36244290Swollman BODY_40_59(55,T,A,B,C,D,E,X); 36344290Swollman BODY_40_59(56,E,T,A,B,C,D,X); 36444290Swollman BODY_40_59(57,D,E,T,A,B,C,X); 36544290Swollman BODY_40_59(58,C,D,E,T,A,B,X); 36644290Swollman BODY_40_59(59,B,C,D,E,T,A,X); 36744290Swollman 36844290Swollman BODY_60_79(60,A,B,C,D,E,T,X); 36944290Swollman BODY_60_79(61,T,A,B,C,D,E,X); 37044290Swollman BODY_60_79(62,E,T,A,B,C,D,X); 37144290Swollman BODY_60_79(63,D,E,T,A,B,C,X); 37244290Swollman BODY_60_79(64,C,D,E,T,A,B,X); 37344290Swollman BODY_60_79(65,B,C,D,E,T,A,X); 37444290Swollman BODY_60_79(66,A,B,C,D,E,T,X); 37544290Swollman BODY_60_79(67,T,A,B,C,D,E,X); 37644290Swollman BODY_60_79(68,E,T,A,B,C,D,X); 37744290Swollman BODY_60_79(69,D,E,T,A,B,C,X); 37844290Swollman BODY_60_79(70,C,D,E,T,A,B,X); 37944290Swollman BODY_60_79(71,B,C,D,E,T,A,X); 38044290Swollman BODY_60_79(72,A,B,C,D,E,T,X); 38144290Swollman BODY_60_79(73,T,A,B,C,D,E,X); 38244290Swollman BODY_60_79(74,E,T,A,B,C,D,X); 38344290Swollman BODY_60_79(75,D,E,T,A,B,C,X); 38444290Swollman BODY_60_79(76,C,D,E,T,A,B,X); 38544290Swollman BODY_60_79(77,B,C,D,E,T,A,X); 38644290Swollman BODY_60_79(78,A,B,C,D,E,T,X); 38744290Swollman BODY_60_79(79,T,A,B,C,D,E,X); 38844290Swollman 38944290Swollman c->h0=(c->h0+E)&0xffffffffL; 39044290Swollman c->h1=(c->h1+T)&0xffffffffL; 39144290Swollman c->h2=(c->h2+A)&0xffffffffL; 39244290Swollman c->h3=(c->h3+B)&0xffffffffL; 39344290Swollman c->h4=(c->h4+C)&0xffffffffL; 39444290Swollman 39544290Swollman num-=64; 39644290Swollman if (num <= 0) break; 39744290Swollman 39844290Swollman A=c->h0; 39944290Swollman B=c->h1; 40044290Swollman C=c->h2; 40144290Swollman D=c->h3; 40244290Swollman E=c->h4; 40344290Swollman 40444290Swollman W+=16; 40544290Swollman } 40644290Swollman } 40744290Swollman 40844290Swollmanvoid SHA_Final(md, c) 40944290Swollmanunsigned char *md; 41044290SwollmanSHA_CTX *c; 41144290Swollman { 41292913Sobrien int i,j; 41392913Sobrien u_int32_t l; 41492913Sobrien u_int32_t *p; 41544290Swollman static unsigned char end[4]={0x80,0x00,0x00,0x00}; 41644290Swollman unsigned char *cp=end; 41744290Swollman 41844290Swollman /* c->num should definitly have room for at least one more byte. */ 41944290Swollman p=c->data; 42044290Swollman j=c->num; 42144290Swollman i=j>>2; 42244290Swollman#ifdef PURIFY 42344290Swollman if ((j&0x03) == 0) p[i]=0; 42444290Swollman#endif 42544290Swollman l=p[i]; 42644290Swollman M_p_c2nl(cp,l,j&0x03); 42744290Swollman p[i]=l; 42844290Swollman i++; 42944290Swollman /* i is the next 'undefined word' */ 43044290Swollman if (c->num >= SHA_LAST_BLOCK) 43144290Swollman { 43244290Swollman for (; i<SHA_LBLOCK; i++) 43344290Swollman p[i]=0; 43444290Swollman sha_block(c,p,64); 43544290Swollman i=0; 43644290Swollman } 43744290Swollman for (; i<(SHA_LBLOCK-2); i++) 43844290Swollman p[i]=0; 43944290Swollman p[SHA_LBLOCK-2]=c->Nh; 44044290Swollman p[SHA_LBLOCK-1]=c->Nl; 44144290Swollman sha_block(c,p,64); 44244290Swollman cp=md; 44344290Swollman l=c->h0; nl2c(l,cp); 44444290Swollman l=c->h1; nl2c(l,cp); 44544290Swollman l=c->h2; nl2c(l,cp); 44644290Swollman l=c->h3; nl2c(l,cp); 44744290Swollman l=c->h4; nl2c(l,cp); 44844290Swollman 44944290Swollman /* clear stuff, sha_block may be leaving some stuff on the stack 45044290Swollman * but I'm not worried :-) */ 45144290Swollman c->num=0; 45244290Swollman/* memset((char *)&c,0,sizeof(c));*/ 45344290Swollman } 45444290Swollman 455