18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** ******************************************************************** 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** md4.c -- Implementation of MD4 Message Digest Algorithm ** 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Updated: 2/16/90 by Ronald L. Rivest ** 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** (C) 1990 RSA Data Security, Inc. ** 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** ******************************************************************** 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** To use MD4: 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** -- Include md4.h in your program 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** -- Declare an MDstruct MD to hold the state of the digest 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** computation. 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** -- Initialize MD using MDbegin(&MD) 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** -- For each full block (64 bytes) X you wish to process, call 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** MD4Update(&MD,X,512) 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** (512 is the number of bits in a full block.) 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** -- For the last block (less than 64 bytes) you wish to process, 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** MD4Update(&MD,X,n) 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** where n is the number of bits in the partial block. A partial 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** block terminates the computation, so every MD computation 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** should terminate by processing a partial block, even if it 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** has n = 0. 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** -- The message digest is available in MD.buffer[0] ... 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** MD.buffer[3]. (Least-significant byte of each word 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** should be output first.) 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** -- You can print out the digest using MDprint(&MD) 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Implementation notes: 318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** This implementation assumes that ints are 32-bit quantities. 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define TRUE 1 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define FALSE 0 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Compile-time includes 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h> 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "md4.h" 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h" 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Compile-time declarations of MD4 "magic constants". 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define I0 0x67452301 /* Initial values for MD buffer */ 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define I1 0xefcdab89 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define I2 0x98badcfe 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define I3 0x10325476 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* C2 and C3 are from Knuth, The Art of Programming, Volume 2 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Table 2, page 660. 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define fs1 3 /* round 1 shift amounts */ 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define fs2 7 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define fs3 11 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define fs4 19 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define gs1 3 /* round 2 shift amounts */ 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define gs2 5 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define gs3 9 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define gs4 13 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define hs1 3 /* round 3 shift amounts */ 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define hs2 9 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define hs3 11 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define hs4 15 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Compile-time macro declarations for MD4. 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Note: The "rot" operator uses the variable "tmp". 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** It assumes tmp is declared as unsigned int, so that the >> 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** operator will shift in zeros rather than extending the sign bit. 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define h(X,Y,Z) (X^Y^Z) 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S))) 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* MD4print(MDp) 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Print message digest buffer MDp as 32 hexadecimal digits. 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Order is from low-order byte of buffer[0] to high-order byte of 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** buffer[3]. 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Each byte is printed with high-order hexadecimal digit first. 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** This is a user-callable routine. 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4Print(MDp) 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4_CTX *MDp; 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i,j; 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i=0;i<4;i++) 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (j=0;j<32;j=j+8) 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printf("%02x",(MDp->buffer[i]>>j) & 0xFF); 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* MD4Init(MDp) 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Initialize message digest buffer MDp. 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** This is a user-callable routine. 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4Init(MDp) 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4_CTX *MDp; 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i; 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->buffer[0] = I0; 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->buffer[1] = I1; 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->buffer[2] = I2; 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->buffer[3] = I3; 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i=0;i<8;i++) MDp->count[i] = 0; 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->done = 0; 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* MDblock(MDp,X) 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Update message digest buffer MDp->buffer using 16-word data block X. 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Assumes all 16 words of X are full of data. 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Does not update MDp->count. 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** This routine is not user-callable. 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMDblock(MDp,Xb) 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4_CTX *MDp; 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectunsigned char *Xb; 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project register unsigned int tmp, A, B, C, D; 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned int X[16]; 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i; 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < 16; ++i) { 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24); 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project Xb += 4; 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project A = MDp->buffer[0]; 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project B = MDp->buffer[1]; 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project C = MDp->buffer[2]; 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project D = MDp->buffer[3]; 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Update the message digest buffer */ 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(A , B , C , D , 0 , fs1); /* Round 1 */ 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(D , A , B , C , 1 , fs2); 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(C , D , A , B , 2 , fs3); 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(B , C , D , A , 3 , fs4); 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(A , B , C , D , 4 , fs1); 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(D , A , B , C , 5 , fs2); 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(C , D , A , B , 6 , fs3); 1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(B , C , D , A , 7 , fs4); 1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(A , B , C , D , 8 , fs1); 1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(D , A , B , C , 9 , fs2); 1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(C , D , A , B , 10 , fs3); 1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(B , C , D , A , 11 , fs4); 1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(A , B , C , D , 12 , fs1); 1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(D , A , B , C , 13 , fs2); 1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(C , D , A , B , 14 , fs3); 1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ff(B , C , D , A , 15 , fs4); 1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(A , B , C , D , 0 , gs1); /* Round 2 */ 1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(D , A , B , C , 4 , gs2); 1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(C , D , A , B , 8 , gs3); 1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(B , C , D , A , 12 , gs4); 1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(A , B , C , D , 1 , gs1); 1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(D , A , B , C , 5 , gs2); 1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(C , D , A , B , 9 , gs3); 1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(B , C , D , A , 13 , gs4); 1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(A , B , C , D , 2 , gs1); 1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(D , A , B , C , 6 , gs2); 1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(C , D , A , B , 10 , gs3); 1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(B , C , D , A , 14 , gs4); 1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(A , B , C , D , 3 , gs1); 1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(D , A , B , C , 7 , gs2); 1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(C , D , A , B , 11 , gs3); 1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project gg(B , C , D , A , 15 , gs4); 1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(A , B , C , D , 0 , hs1); /* Round 3 */ 1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(D , A , B , C , 8 , hs2); 1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(C , D , A , B , 4 , hs3); 1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(B , C , D , A , 12 , hs4); 1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(A , B , C , D , 2 , hs1); 1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(D , A , B , C , 10 , hs2); 1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(C , D , A , B , 6 , hs3); 1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(B , C , D , A , 14 , hs4); 1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(A , B , C , D , 1 , hs1); 1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(D , A , B , C , 9 , hs2); 1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(C , D , A , B , 5 , hs3); 1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(B , C , D , A , 13 , hs4); 1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(A , B , C , D , 3 , hs1); 1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(D , A , B , C , 11 , hs2); 1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(C , D , A , B , 7 , hs3); 1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hh(B , C , D , A , 15 , hs4); 1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->buffer[0] += A; 1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->buffer[1] += B; 1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->buffer[2] += C; 1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->buffer[3] += D; 1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* MD4Update(MDp,X,count) 1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Input: X -- a pointer to an array of unsigned characters. 1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** count -- the number of bits of X to use. 1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** (if not a multiple of 8, uses high bits of last byte.) 1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Update MDp using the number of bits of X given by count. 2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** This is the basic input routine for an MD4 user. 2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** The routine completes the MD computation when count < 512, so 2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** every MD computation should end with one call to MD4Update with a 2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** count less than 512. A call with count 0 will be ignored if the 2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** MD has already been terminated (done != 0), so an extra call with 2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** count 0 can be given as a "courtesy close" to force termination 2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** if desired. 2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4Update(MDp,X,count) 2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4_CTX *MDp; 2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectunsigned char *X; 2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectunsigned int count; 2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned int i, tmp, bit, byte, mask; 2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char XX[64]; 2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned char *p; 2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* return with no error if this is a courtesy close with count 2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ** zero and MDp->done is true. 2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (count == 0 && MDp->done) return; 2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* check to see if MD is already done and report error */ 2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (MDp->done) 2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { printf("\nError: MD4Update MD already done."); return; } 2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Add count to MDp->count */ 2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tmp = count; 2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = MDp->count; 2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while (tmp) 2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { tmp += *p; 2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *p++ = tmp; 2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tmp = tmp >> 8; 2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Process data */ 2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (count == 512) 2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { /* Full block of data to handle */ 2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDblock(MDp,X); 2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else if (count > 512) /* Check for count too large */ 2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printf("\nError: MD4Update called with illegal count value %d.", 2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project count); 2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else /* partial block -- must be last block so finish up */ 2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Find out how many bytes and residual bits there are */ 2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project byte = count >> 3; 2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bit = count & 7; 2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Copy X into XX since we need to modify it */ 2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i=0;i<=byte;i++) XX[i] = X[i]; 2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i=byte+1;i<64;i++) XX[i] = 0; 2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Add padding '1' bit and low-order zeros in last byte */ 2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project mask = 1 << (7 - bit); 2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project XX[byte] = (XX[byte] | mask) & ~( mask - 1); 2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* If room for bit count, finish up with this block */ 2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (byte <= 55) 2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; 2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDblock(MDp,XX); 2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else /* need to do two blocks to finish up */ 2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDblock(MDp,XX); 2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i=0;i<56;i++) XX[i] = 0; 2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; 2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDblock(MDp,XX); 2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Set flag saying we're done with MD computation */ 2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MDp->done = 1; 2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** Finish up MD4 computation and return message digest. 2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4Final(buf, MD) 2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectunsigned char *buf; 2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectMD4_CTX *MD; 2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i, j; 2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project unsigned int w; 2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project MD4Update(MD, NULL, 0); 2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < 4; ++i) { 2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project w = MD->buffer[i]; 2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (j = 0; j < 4; ++j) { 2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *buf++ = w; 2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project w >>= 8; 2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project** End of md4.c 2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project****************************(cut)***********************************/ 299