The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/crypto/md5.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $     */
    2 /*
    3  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. Neither the name of the project nor the names of its contributors
   15  *    may be used to endorse or promote products derived from this software
   16  *    without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD: releng/5.2/sys/crypto/md5.c 116174 2003-06-10 21:44:29Z obrien $");
   33 
   34 #include <sys/types.h>
   35 #include <sys/cdefs.h>
   36 #include <sys/time.h>
   37 #include <sys/systm.h>
   38 #include <crypto/md5.h>
   39 
   40 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
   41 
   42 #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
   43 #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
   44 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
   45 #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
   46 
   47 #define ROUND1(a, b, c, d, k, s, i) { \
   48         (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
   49         (a) = SHIFT((a), (s)); \
   50         (a) = (b) + (a); \
   51 }
   52 
   53 #define ROUND2(a, b, c, d, k, s, i) { \
   54         (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
   55         (a) = SHIFT((a), (s)); \
   56         (a) = (b) + (a); \
   57 }
   58 
   59 #define ROUND3(a, b, c, d, k, s, i) { \
   60         (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
   61         (a) = SHIFT((a), (s)); \
   62         (a) = (b) + (a); \
   63 }
   64 
   65 #define ROUND4(a, b, c, d, k, s, i) { \
   66         (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
   67         (a) = SHIFT((a), (s)); \
   68         (a) = (b) + (a); \
   69 }
   70 
   71 #define Sa       7
   72 #define Sb      12
   73 #define Sc      17
   74 #define Sd      22
   75 
   76 #define Se       5
   77 #define Sf       9
   78 #define Sg      14
   79 #define Sh      20
   80 
   81 #define Si       4
   82 #define Sj      11
   83 #define Sk      16
   84 #define Sl      23
   85 
   86 #define Sm       6
   87 #define Sn      10
   88 #define So      15
   89 #define Sp      21
   90 
   91 #define MD5_A0  0x67452301
   92 #define MD5_B0  0xefcdab89
   93 #define MD5_C0  0x98badcfe
   94 #define MD5_D0  0x10325476
   95 
   96 /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
   97 static const u_int32_t T[65] = {
   98         0,
   99         0xd76aa478,     0xe8c7b756,     0x242070db,     0xc1bdceee,
  100         0xf57c0faf,     0x4787c62a,     0xa8304613,     0xfd469501,
  101         0x698098d8,     0x8b44f7af,     0xffff5bb1,     0x895cd7be,
  102         0x6b901122,     0xfd987193,     0xa679438e,     0x49b40821,
  103 
  104         0xf61e2562,     0xc040b340,     0x265e5a51,     0xe9b6c7aa,
  105         0xd62f105d,     0x2441453,      0xd8a1e681,     0xe7d3fbc8,
  106         0x21e1cde6,     0xc33707d6,     0xf4d50d87,     0x455a14ed,
  107         0xa9e3e905,     0xfcefa3f8,     0x676f02d9,     0x8d2a4c8a,
  108 
  109         0xfffa3942,     0x8771f681,     0x6d9d6122,     0xfde5380c,
  110         0xa4beea44,     0x4bdecfa9,     0xf6bb4b60,     0xbebfbc70,
  111         0x289b7ec6,     0xeaa127fa,     0xd4ef3085,     0x4881d05,
  112         0xd9d4d039,     0xe6db99e5,     0x1fa27cf8,     0xc4ac5665,
  113 
  114         0xf4292244,     0x432aff97,     0xab9423a7,     0xfc93a039,
  115         0x655b59c3,     0x8f0ccc92,     0xffeff47d,     0x85845dd1,
  116         0x6fa87e4f,     0xfe2ce6e0,     0xa3014314,     0x4e0811a1,
  117         0xf7537e82,     0xbd3af235,     0x2ad7d2bb,     0xeb86d391,
  118 };
  119 
  120 static const u_int8_t md5_paddat[MD5_BUFLEN] = {
  121         0x80,   0,      0,      0,      0,      0,      0,      0,
  122         0,      0,      0,      0,      0,      0,      0,      0,
  123         0,      0,      0,      0,      0,      0,      0,      0,
  124         0,      0,      0,      0,      0,      0,      0,      0,
  125         0,      0,      0,      0,      0,      0,      0,      0,
  126         0,      0,      0,      0,      0,      0,      0,      0,
  127         0,      0,      0,      0,      0,      0,      0,      0,
  128         0,      0,      0,      0,      0,      0,      0,      0,      
  129 };
  130 
  131 static void md5_calc(u_int8_t *, md5_ctxt *);
  132 
  133 void md5_init(ctxt)
  134         md5_ctxt *ctxt;
  135 {
  136         ctxt->md5_n = 0;
  137         ctxt->md5_i = 0;
  138         ctxt->md5_sta = MD5_A0;
  139         ctxt->md5_stb = MD5_B0;
  140         ctxt->md5_stc = MD5_C0;
  141         ctxt->md5_std = MD5_D0;
  142         bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
  143 }
  144 
  145 void md5_loop(ctxt, input, len)
  146         md5_ctxt *ctxt;
  147         u_int8_t *input;
  148         u_int len; /* number of bytes */
  149 {
  150         u_int gap, i;
  151 
  152         ctxt->md5_n += len * 8; /* byte to bit */
  153         gap = MD5_BUFLEN - ctxt->md5_i;
  154 
  155         if (len >= gap) {
  156                 bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  157                         gap);
  158                 md5_calc(ctxt->md5_buf, ctxt);
  159 
  160                 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
  161                         md5_calc((u_int8_t *)(input + i), ctxt);
  162                 }
  163                 
  164                 ctxt->md5_i = len - i;
  165                 bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
  166         } else {
  167                 bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  168                         len);
  169                 ctxt->md5_i += len;
  170         }
  171 }
  172 
  173 void md5_pad(ctxt)
  174         md5_ctxt *ctxt;
  175 {
  176         u_int gap;
  177 
  178         /* Don't count up padding. Keep md5_n. */       
  179         gap = MD5_BUFLEN - ctxt->md5_i;
  180         if (gap > 8) {
  181                 bcopy(md5_paddat,
  182                       (void *)(ctxt->md5_buf + ctxt->md5_i),
  183                       gap - sizeof(ctxt->md5_n));
  184         } else {
  185                 /* including gap == 8 */
  186                 bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
  187                         gap);
  188                 md5_calc(ctxt->md5_buf, ctxt);
  189                 bcopy((md5_paddat + gap),
  190                       (void *)ctxt->md5_buf,
  191                       MD5_BUFLEN - sizeof(ctxt->md5_n));
  192         }
  193 
  194         /* 8 byte word */       
  195 #if BYTE_ORDER == LITTLE_ENDIAN
  196         bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
  197 #endif
  198 #if BYTE_ORDER == BIG_ENDIAN
  199         ctxt->md5_buf[56] = ctxt->md5_n8[7];
  200         ctxt->md5_buf[57] = ctxt->md5_n8[6];
  201         ctxt->md5_buf[58] = ctxt->md5_n8[5];
  202         ctxt->md5_buf[59] = ctxt->md5_n8[4];
  203         ctxt->md5_buf[60] = ctxt->md5_n8[3];
  204         ctxt->md5_buf[61] = ctxt->md5_n8[2];
  205         ctxt->md5_buf[62] = ctxt->md5_n8[1];
  206         ctxt->md5_buf[63] = ctxt->md5_n8[0];
  207 #endif
  208 
  209         md5_calc(ctxt->md5_buf, ctxt);
  210 }
  211 
  212 void md5_result(digest, ctxt)
  213         u_int8_t *digest;
  214         md5_ctxt *ctxt;
  215 {
  216         /* 4 byte words */
  217 #if BYTE_ORDER == LITTLE_ENDIAN
  218         bcopy(&ctxt->md5_st8[0], digest, 16);
  219 #endif
  220 #if BYTE_ORDER == BIG_ENDIAN
  221         digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
  222         digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
  223         digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
  224         digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
  225         digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
  226         digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
  227         digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
  228         digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
  229 #endif
  230 }
  231 
  232 #if BYTE_ORDER == BIG_ENDIAN
  233 u_int32_t X[16];
  234 #endif
  235 
  236 static void md5_calc(b64, ctxt)
  237         u_int8_t *b64;
  238         md5_ctxt *ctxt;
  239 {
  240         u_int32_t A = ctxt->md5_sta;
  241         u_int32_t B = ctxt->md5_stb;
  242         u_int32_t C = ctxt->md5_stc;
  243         u_int32_t D = ctxt->md5_std;
  244 #if BYTE_ORDER == LITTLE_ENDIAN
  245         u_int32_t *X = (u_int32_t *)b64;
  246 #endif  
  247 #if BYTE_ORDER == BIG_ENDIAN
  248         /* 4 byte words */
  249         /* what a brute force but fast! */
  250         u_int8_t *y = (u_int8_t *)X;
  251         y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
  252         y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
  253         y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
  254         y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
  255         y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
  256         y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
  257         y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
  258         y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
  259         y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
  260         y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
  261         y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
  262         y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
  263         y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
  264         y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
  265         y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
  266         y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
  267 #endif
  268 
  269         ROUND1(A, B, C, D,  0, Sa,  1); ROUND1(D, A, B, C,  1, Sb,  2);
  270         ROUND1(C, D, A, B,  2, Sc,  3); ROUND1(B, C, D, A,  3, Sd,  4);
  271         ROUND1(A, B, C, D,  4, Sa,  5); ROUND1(D, A, B, C,  5, Sb,  6);
  272         ROUND1(C, D, A, B,  6, Sc,  7); ROUND1(B, C, D, A,  7, Sd,  8);
  273         ROUND1(A, B, C, D,  8, Sa,  9); ROUND1(D, A, B, C,  9, Sb, 10);
  274         ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
  275         ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
  276         ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
  277         
  278         ROUND2(A, B, C, D,  1, Se, 17); ROUND2(D, A, B, C,  6, Sf, 18);
  279         ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A,  0, Sh, 20);
  280         ROUND2(A, B, C, D,  5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
  281         ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A,  4, Sh, 24);
  282         ROUND2(A, B, C, D,  9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
  283         ROUND2(C, D, A, B,  3, Sg, 27); ROUND2(B, C, D, A,  8, Sh, 28);
  284         ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C,  2, Sf, 30);
  285         ROUND2(C, D, A, B,  7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
  286 
  287         ROUND3(A, B, C, D,  5, Si, 33); ROUND3(D, A, B, C,  8, Sj, 34);
  288         ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
  289         ROUND3(A, B, C, D,  1, Si, 37); ROUND3(D, A, B, C,  4, Sj, 38);
  290         ROUND3(C, D, A, B,  7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
  291         ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C,  0, Sj, 42);
  292         ROUND3(C, D, A, B,  3, Sk, 43); ROUND3(B, C, D, A,  6, Sl, 44);
  293         ROUND3(A, B, C, D,  9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
  294         ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A,  2, Sl, 48);
  295         
  296         ROUND4(A, B, C, D,  0, Sm, 49); ROUND4(D, A, B, C,  7, Sn, 50); 
  297         ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A,  5, Sp, 52); 
  298         ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C,  3, Sn, 54); 
  299         ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A,  1, Sp, 56); 
  300         ROUND4(A, B, C, D,  8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58); 
  301         ROUND4(C, D, A, B,  6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60); 
  302         ROUND4(A, B, C, D,  4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62); 
  303         ROUND4(C, D, A, B,  2, So, 63); ROUND4(B, C, D, A,  9, Sp, 64);
  304 
  305         ctxt->md5_sta += A;
  306         ctxt->md5_stb += B;
  307         ctxt->md5_stc += C;
  308         ctxt->md5_std += D;
  309 }

Cache object: f27721436ede9885e5ad168bf23975a3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.