xref: /illumos-gate/usr/src/lib/gss_mechs/mech_krb5/crypto/md4/md4.c (revision 159d09a20817016f09b3ea28d1bdada4a336bb91)
17c478bd9Sstevel@tonic-gate /*
2*159d09a2SMark Phalan  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate 
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate  *	lib/crypto/md4/md4.c
97c478bd9Sstevel@tonic-gate  */
107c478bd9Sstevel@tonic-gate 
117c478bd9Sstevel@tonic-gate /*
127c478bd9Sstevel@tonic-gate  **********************************************************************
137c478bd9Sstevel@tonic-gate  ** md4.c                                                            **
147c478bd9Sstevel@tonic-gate  ** RSA Data Security, Inc. MD4 Message Digest Algorithm             **
157c478bd9Sstevel@tonic-gate  ** Created: 2/17/90 RLR                                             **
167c478bd9Sstevel@tonic-gate  ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                  **
177c478bd9Sstevel@tonic-gate  **********************************************************************
187c478bd9Sstevel@tonic-gate  */
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate /*
217c478bd9Sstevel@tonic-gate  **********************************************************************
227c478bd9Sstevel@tonic-gate  ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
237c478bd9Sstevel@tonic-gate  **                                                                  **
247c478bd9Sstevel@tonic-gate  ** License to copy and use this software is granted provided that   **
257c478bd9Sstevel@tonic-gate  ** it is identified as the "RSA Data Security, Inc. MD4 Message     **
267c478bd9Sstevel@tonic-gate  ** Digest Algorithm" in all material mentioning or referencing this **
277c478bd9Sstevel@tonic-gate  ** software or this function.                                       **
287c478bd9Sstevel@tonic-gate  **                                                                  **
297c478bd9Sstevel@tonic-gate  ** License is also granted to make and use derivative works         **
307c478bd9Sstevel@tonic-gate  ** provided that such works are identified as "derived from the RSA **
317c478bd9Sstevel@tonic-gate  ** Data Security, Inc. MD4 Message Digest Algorithm" in all         **
327c478bd9Sstevel@tonic-gate  ** material mentioning or referencing the derived work.             **
337c478bd9Sstevel@tonic-gate  **                                                                  **
347c478bd9Sstevel@tonic-gate  ** RSA Data Security, Inc. makes no representations concerning      **
357c478bd9Sstevel@tonic-gate  ** either the merchantability of this software or the suitability   **
367c478bd9Sstevel@tonic-gate  ** of this software for any particular purpose.  It is provided "as **
377c478bd9Sstevel@tonic-gate  ** is" without express or implied warranty of any kind.             **
387c478bd9Sstevel@tonic-gate  **                                                                  **
397c478bd9Sstevel@tonic-gate  ** These notices must be retained in any copies of any part of this **
407c478bd9Sstevel@tonic-gate  ** documentation and/or software.                                   **
417c478bd9Sstevel@tonic-gate  **********************************************************************
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate 
44*159d09a2SMark Phalan #include "k5-int.h"
45*159d09a2SMark Phalan #include "rsa-md4.h"
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /* forward declaration */
487c478bd9Sstevel@tonic-gate static void Transform (krb5_ui_4 *, krb5_ui_4 *);
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate static const unsigned char PADDING[64] = {
517c478bd9Sstevel@tonic-gate   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
527c478bd9Sstevel@tonic-gate   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537c478bd9Sstevel@tonic-gate   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547c478bd9Sstevel@tonic-gate   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557c478bd9Sstevel@tonic-gate   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567c478bd9Sstevel@tonic-gate   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577c478bd9Sstevel@tonic-gate   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587c478bd9Sstevel@tonic-gate   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
597c478bd9Sstevel@tonic-gate };
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate /* F, G and H are basic MD4 functions: selection, majority, parity */
627c478bd9Sstevel@tonic-gate #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
637c478bd9Sstevel@tonic-gate #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
647c478bd9Sstevel@tonic-gate #define H(x, y, z) ((x) ^ (y) ^ (z))
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /* ROTATE_LEFT rotates x left n bits */
677c478bd9Sstevel@tonic-gate #define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n))))
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */
707c478bd9Sstevel@tonic-gate /* Rotation is separate from addition to prevent recomputation */
717c478bd9Sstevel@tonic-gate #define FF(a, b, c, d, x, s) \
727c478bd9Sstevel@tonic-gate   {(a) += F ((b), (c), (d)) + (x); \
737c478bd9Sstevel@tonic-gate    (a) &= 0xffffffff; \
747c478bd9Sstevel@tonic-gate    (a) = ROTATE_LEFT ((a), (s));}
757c478bd9Sstevel@tonic-gate #define GG(a, b, c, d, x, s) \
767c478bd9Sstevel@tonic-gate   {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \
777c478bd9Sstevel@tonic-gate    (a) &= 0xffffffff; \
787c478bd9Sstevel@tonic-gate    (a) = ROTATE_LEFT ((a), (s));}
797c478bd9Sstevel@tonic-gate #define HH(a, b, c, d, x, s) \
807c478bd9Sstevel@tonic-gate   {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \
817c478bd9Sstevel@tonic-gate    (a) &= 0xffffffff; \
827c478bd9Sstevel@tonic-gate    (a) = ROTATE_LEFT ((a), (s));}
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate void
krb5_MD4Init(krb5_MD4_CTX * mdContext)85*159d09a2SMark Phalan krb5_MD4Init (krb5_MD4_CTX *mdContext)
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate   mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate   /* Load magic initialization constants.
907c478bd9Sstevel@tonic-gate    */
917c478bd9Sstevel@tonic-gate   mdContext->buf[0] = 0x67452301UL;
927c478bd9Sstevel@tonic-gate   mdContext->buf[1] = 0xefcdab89UL;
937c478bd9Sstevel@tonic-gate   mdContext->buf[2] = 0x98badcfeUL;
947c478bd9Sstevel@tonic-gate   mdContext->buf[3] = 0x10325476UL;
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate void
krb5_MD4Update(krb5_MD4_CTX * mdContext,const unsigned char * inBuf,unsigned int inLen)98*159d09a2SMark Phalan krb5_MD4Update (krb5_MD4_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen)
997c478bd9Sstevel@tonic-gate {
1007c478bd9Sstevel@tonic-gate   krb5_ui_4 in[16];
1017c478bd9Sstevel@tonic-gate   int mdi;
1027c478bd9Sstevel@tonic-gate   unsigned int i, ii;
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate   /* compute number of bytes mod 64 */
1057c478bd9Sstevel@tonic-gate   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate   /* update number of bits */
1087c478bd9Sstevel@tonic-gate   if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0])
1097c478bd9Sstevel@tonic-gate     mdContext->i[1]++;
1107c478bd9Sstevel@tonic-gate   mdContext->i[0] += ((krb5_ui_4)inLen << 3);
1117c478bd9Sstevel@tonic-gate   mdContext->i[1] += ((krb5_ui_4)inLen >> 29);
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate   while (inLen--) {
1147c478bd9Sstevel@tonic-gate     /* add new character to buffer, increment mdi */
1157c478bd9Sstevel@tonic-gate     mdContext->in[mdi++] = *inBuf++;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate     /* transform if necessary */
1187c478bd9Sstevel@tonic-gate     if (mdi == 0x40) {
1197c478bd9Sstevel@tonic-gate       for (i = 0, ii = 0; i < 16; i++, ii += 4)
1207c478bd9Sstevel@tonic-gate         in[i] = (((krb5_ui_4)mdContext->in[ii+3]) << 24) |
1217c478bd9Sstevel@tonic-gate                 (((krb5_ui_4)mdContext->in[ii+2]) << 16) |
1227c478bd9Sstevel@tonic-gate                 (((krb5_ui_4)mdContext->in[ii+1]) << 8) |
1237c478bd9Sstevel@tonic-gate                 ((krb5_ui_4)mdContext->in[ii]);
1247c478bd9Sstevel@tonic-gate       Transform (mdContext->buf, in);
1257c478bd9Sstevel@tonic-gate       mdi = 0;
1267c478bd9Sstevel@tonic-gate     }
1277c478bd9Sstevel@tonic-gate   }
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate void
krb5_MD4Final(krb5_MD4_CTX * mdContext)131*159d09a2SMark Phalan krb5_MD4Final (krb5_MD4_CTX *mdContext)
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate   krb5_ui_4 in[16];
1347c478bd9Sstevel@tonic-gate   int mdi;
1357c478bd9Sstevel@tonic-gate   unsigned int i, ii;
1367c478bd9Sstevel@tonic-gate   unsigned int padLen;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate   /* save number of bits */
1397c478bd9Sstevel@tonic-gate   in[14] = mdContext->i[0];
1407c478bd9Sstevel@tonic-gate   in[15] = mdContext->i[1];
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate   /* compute number of bytes mod 64 */
1437c478bd9Sstevel@tonic-gate   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate   /* pad out to 56 mod 64 */
1467c478bd9Sstevel@tonic-gate   padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
1477c478bd9Sstevel@tonic-gate   krb5_MD4Update (mdContext, PADDING, padLen);
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate   /* append length in bits and transform */
1507c478bd9Sstevel@tonic-gate   for (i = 0, ii = 0; i < 14; i++, ii += 4)
1517c478bd9Sstevel@tonic-gate     in[i] = (((krb5_ui_4)mdContext->in[ii+3]) << 24) |
1527c478bd9Sstevel@tonic-gate             (((krb5_ui_4)mdContext->in[ii+2]) << 16) |
1537c478bd9Sstevel@tonic-gate             (((krb5_ui_4)mdContext->in[ii+1]) << 8) |
1547c478bd9Sstevel@tonic-gate             ((krb5_ui_4)mdContext->in[ii]);
1557c478bd9Sstevel@tonic-gate   Transform (mdContext->buf, in);
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate   /* store buffer in digest */
1597c478bd9Sstevel@tonic-gate   for (i = 0, ii = 0; i < 4; i++, ii += 4) {
1607c478bd9Sstevel@tonic-gate     mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
1617c478bd9Sstevel@tonic-gate     mdContext->digest[ii+1] =
1627c478bd9Sstevel@tonic-gate       (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
1637c478bd9Sstevel@tonic-gate     mdContext->digest[ii+2] =
1647c478bd9Sstevel@tonic-gate       (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
1657c478bd9Sstevel@tonic-gate     mdContext->digest[ii+3] =
1667c478bd9Sstevel@tonic-gate       (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
1677c478bd9Sstevel@tonic-gate   }
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate /* Basic MD4 step. Transform buf based on in.
1717c478bd9Sstevel@tonic-gate  */
Transform(krb5_ui_4 * buf,krb5_ui_4 * in)172*159d09a2SMark Phalan static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in)
1737c478bd9Sstevel@tonic-gate {
1747c478bd9Sstevel@tonic-gate   register krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
1757c478bd9Sstevel@tonic-gate 
176*159d09a2SMark Phalan #ifdef CONFIG_SMALL
177*159d09a2SMark Phalan   int i;
178*159d09a2SMark Phalan #define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; }
179*159d09a2SMark Phalan   for (i = 0; i < 16; i++) {
180*159d09a2SMark Phalan       static const unsigned char round1consts[] = { 3, 7, 11, 19, };
181*159d09a2SMark Phalan       FF (a, b, c, d, in[i], round1consts[i%4]); ROTATE;
182*159d09a2SMark Phalan   }
183*159d09a2SMark Phalan   for (i = 0; i < 16; i++) {
184*159d09a2SMark Phalan       static const unsigned char round2indices[] = {
185*159d09a2SMark Phalan 	  0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15
186*159d09a2SMark Phalan       };
187*159d09a2SMark Phalan       static const unsigned char round2consts[] = { 3, 5, 9, 13 };
188*159d09a2SMark Phalan       GG (a, b, c, d, in[round2indices[i]], round2consts[i%4]); ROTATE;
189*159d09a2SMark Phalan   }
190*159d09a2SMark Phalan   for (i = 0; i < 16; i++) {
191*159d09a2SMark Phalan       static const unsigned char round3indices[] = {
192*159d09a2SMark Phalan 	  0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
193*159d09a2SMark Phalan       };
194*159d09a2SMark Phalan       static const unsigned char round3consts[] = { 3, 9, 11, 15 };
195*159d09a2SMark Phalan       HH (a, b, c, d, in[round3indices[i]], round3consts[i%4]); ROTATE;
196*159d09a2SMark Phalan   }
197*159d09a2SMark Phalan #else
1987c478bd9Sstevel@tonic-gate   /* Round 1 */
1997c478bd9Sstevel@tonic-gate   FF (a, b, c, d, in[ 0],  3);
2007c478bd9Sstevel@tonic-gate   FF (d, a, b, c, in[ 1],  7);
2017c478bd9Sstevel@tonic-gate   FF (c, d, a, b, in[ 2], 11);
2027c478bd9Sstevel@tonic-gate   FF (b, c, d, a, in[ 3], 19);
2037c478bd9Sstevel@tonic-gate   FF (a, b, c, d, in[ 4],  3);
2047c478bd9Sstevel@tonic-gate   FF (d, a, b, c, in[ 5],  7);
2057c478bd9Sstevel@tonic-gate   FF (c, d, a, b, in[ 6], 11);
2067c478bd9Sstevel@tonic-gate   FF (b, c, d, a, in[ 7], 19);
2077c478bd9Sstevel@tonic-gate   FF (a, b, c, d, in[ 8],  3);
2087c478bd9Sstevel@tonic-gate   FF (d, a, b, c, in[ 9],  7);
2097c478bd9Sstevel@tonic-gate   FF (c, d, a, b, in[10], 11);
2107c478bd9Sstevel@tonic-gate   FF (b, c, d, a, in[11], 19);
2117c478bd9Sstevel@tonic-gate   FF (a, b, c, d, in[12],  3);
2127c478bd9Sstevel@tonic-gate   FF (d, a, b, c, in[13],  7);
2137c478bd9Sstevel@tonic-gate   FF (c, d, a, b, in[14], 11);
2147c478bd9Sstevel@tonic-gate   FF (b, c, d, a, in[15], 19);
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate   /* Round 2 */
2177c478bd9Sstevel@tonic-gate   GG (a, b, c, d, in[ 0],  3);
2187c478bd9Sstevel@tonic-gate   GG (d, a, b, c, in[ 4],  5);
2197c478bd9Sstevel@tonic-gate   GG (c, d, a, b, in[ 8],  9);
2207c478bd9Sstevel@tonic-gate   GG (b, c, d, a, in[12], 13);
2217c478bd9Sstevel@tonic-gate   GG (a, b, c, d, in[ 1],  3);
2227c478bd9Sstevel@tonic-gate   GG (d, a, b, c, in[ 5],  5);
2237c478bd9Sstevel@tonic-gate   GG (c, d, a, b, in[ 9],  9);
2247c478bd9Sstevel@tonic-gate   GG (b, c, d, a, in[13], 13);
2257c478bd9Sstevel@tonic-gate   GG (a, b, c, d, in[ 2],  3);
2267c478bd9Sstevel@tonic-gate   GG (d, a, b, c, in[ 6],  5);
2277c478bd9Sstevel@tonic-gate   GG (c, d, a, b, in[10],  9);
2287c478bd9Sstevel@tonic-gate   GG (b, c, d, a, in[14], 13);
2297c478bd9Sstevel@tonic-gate   GG (a, b, c, d, in[ 3],  3);
2307c478bd9Sstevel@tonic-gate   GG (d, a, b, c, in[ 7],  5);
2317c478bd9Sstevel@tonic-gate   GG (c, d, a, b, in[11],  9);
2327c478bd9Sstevel@tonic-gate   GG (b, c, d, a, in[15], 13);
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate   /* Round 3 */
2357c478bd9Sstevel@tonic-gate   HH (a, b, c, d, in[ 0],  3);
2367c478bd9Sstevel@tonic-gate   HH (d, a, b, c, in[ 8],  9);
2377c478bd9Sstevel@tonic-gate   HH (c, d, a, b, in[ 4], 11);
2387c478bd9Sstevel@tonic-gate   HH (b, c, d, a, in[12], 15);
2397c478bd9Sstevel@tonic-gate   HH (a, b, c, d, in[ 2],  3);
2407c478bd9Sstevel@tonic-gate   HH (d, a, b, c, in[10],  9);
2417c478bd9Sstevel@tonic-gate   HH (c, d, a, b, in[ 6], 11);
2427c478bd9Sstevel@tonic-gate   HH (b, c, d, a, in[14], 15);
2437c478bd9Sstevel@tonic-gate   HH (a, b, c, d, in[ 1],  3);
2447c478bd9Sstevel@tonic-gate   HH (d, a, b, c, in[ 9],  9);
2457c478bd9Sstevel@tonic-gate   HH (c, d, a, b, in[ 5], 11);
2467c478bd9Sstevel@tonic-gate   HH (b, c, d, a, in[13], 15);
2477c478bd9Sstevel@tonic-gate   HH (a, b, c, d, in[ 3],  3);
2487c478bd9Sstevel@tonic-gate   HH (d, a, b, c, in[11],  9);
2497c478bd9Sstevel@tonic-gate   HH (c, d, a, b, in[ 7], 11);
2507c478bd9Sstevel@tonic-gate   HH (b, c, d, a, in[15], 15);
251*159d09a2SMark Phalan #endif
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate   buf[0] += a;
2547c478bd9Sstevel@tonic-gate   buf[1] += b;
2557c478bd9Sstevel@tonic-gate   buf[2] += c;
2567c478bd9Sstevel@tonic-gate   buf[3] += d;
2577c478bd9Sstevel@tonic-gate }
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate /*
2607c478bd9Sstevel@tonic-gate  **********************************************************************
2617c478bd9Sstevel@tonic-gate  ** End of md4.c                                                     **
2627c478bd9Sstevel@tonic-gate  ******************************* (cut) ********************************
2637c478bd9Sstevel@tonic-gate  */
264