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

Cache object: 0fe1f2901e248c3c4293ed2ad169bb86


[ 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.