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