"Fossies" - the Fresh Open Source Software Archive

Member "s-nail-14.9.7/rfc1321.h" (16 Feb 2018, 12204 Bytes) of package /linux/misc/s-nail-14.9.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rfc1321.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 14.9.6_vs_14.9.7.

    1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
    2  *@ RFC 1321 derived MD5 algorithm implementation.
    3  *@ This is included by nailfuns.h if 'HAVE_MD5 && !HAVE_XSSL_MD5',
    4  *@ and contains MD5.H as well as MD5C.C from the RFC.
    5  *
    6  * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
    7  * Copyright (c) 2012 - 2018 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
    8  */
    9 
   10 /* MD5.H - header file for MD5C.C
   11  */
   12 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   13 rights reserved.
   14 
   15 License to copy and use this software is granted provided that it
   16 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   17 Algorithm" in all material mentioning or referencing this software
   18 or this function.
   19 
   20 License is also granted to make and use derivative works provided
   21 that such works are identified as "derived from the RSA Data
   22 Security, Inc. MD5 Message-Digest Algorithm" in all material
   23 mentioning or referencing the derived work.
   24 
   25 RSA Data Security, Inc. makes no representations concerning either
   26 the merchantability of this software or the suitability of this
   27 software for any particular purpose. It is provided "as is"
   28 without express or implied warranty of any kind.
   29 
   30 These notices must be retained in any copies of any part of this
   31 documentation and/or software.
   32  */
   33 
   34 /*
   35  * This version of MD5 has been changed such that any unsigned type with
   36  * at least 32 bits is acceptable. This is important e.g. for Cray vector
   37  * machines which provide only 64-bit integers.
   38  */
   39 typedef unsigned long   md5_type;
   40 
   41 typedef struct {
   42     md5_type state[4];  /* state (ABCD) */
   43     md5_type count[2];  /* number of bits, modulo 2^64 (lsb first) */
   44     unsigned char   buffer[64]; /* input buffer */
   45 } md5_ctx;
   46 
   47 FL void md5_init(md5_ctx *);
   48 FL void md5_update(md5_ctx *, unsigned char *, unsigned int);
   49 FL void md5_final(unsigned char[16], md5_ctx *);
   50 
   51 #ifdef n_MAIN_SOURCE
   52 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
   53  */
   54 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   55 rights reserved.
   56 
   57 License to copy and use this software is granted provided that it
   58 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   59 Algorithm" in all material mentioning or referencing this software
   60 or this function.
   61 
   62 License is also granted to make and use derivative works provided
   63 that such works are identified as "derived from the RSA Data
   64 Security, Inc. MD5 Message-Digest Algorithm" in all material
   65 mentioning or referencing the derived work.
   66 
   67 RSA Data Security, Inc. makes no representations concerning either
   68 the merchantability of this software or the suitability of this
   69 software for any particular purpose. It is provided "as is"
   70 without express or implied warranty of any kind.
   71 
   72 These notices must be retained in any copies of any part of this
   73 documentation and/or software.
   74  */
   75 
   76 # include <string.h>
   77 
   78 #define UINT4B_MAX  0xFFFFFFFFul
   79 
   80 /* Constants for MD5Transform routine.
   81  */
   82 #define S11 7
   83 #define S12 12
   84 #define S13 17
   85 #define S14 22
   86 #define S21 5
   87 #define S22 9
   88 #define S23 14
   89 #define S24 20
   90 #define S31 4
   91 #define S32 11
   92 #define S33 16
   93 #define S34 23
   94 #define S41 6
   95 #define S42 10
   96 #define S43 15
   97 #define S44 21
   98 
   99 static unsigned char PADDING[64] = {
  100   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  101   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  102   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  103 };
  104 
  105 /*
  106 #define F(x,y,z)    (((x) & (y))  |  ((~(x)) & (z)))
  107 #define G(x,y,z)    (((x) & (z))  |  ((y) & (~(z))))
  108 */
  109 
  110 /* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
  111  * simplified to the code below.  Wei attributes these optimizations
  112  * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
  113  */
  114 #define F(b,c,d)    ((((c) ^ (d)) & (b)) ^ (d))
  115 #define G(b,c,d)    ((((b) ^ (c)) & (d)) ^ (c))
  116 #define H(b,c,d)    ((b) ^ (c) ^ (d))
  117 #define I(b,c,d)    (((~(d) & UINT4B_MAX) | (b)) ^ (c))
  118 
  119 /* ROTATE_LEFT rotates x left n bits.
  120  */
  121 #define ROTATE_LEFT(x, n) ((((x) << (n)) & UINT4B_MAX) | ((x) >> (32 - (n))))
  122 
  123 /*
  124  * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  125  * Rotation is separate from addition to prevent recomputation.
  126  */
  127 #define FF(a, b, c, d, x, s, ac) { \
  128     (a) = ((a) + F(b, c, d) + (x) + ((ac) & UINT4B_MAX)) & UINT4B_MAX; \
  129     (a) = ROTATE_LEFT((a), (s)); \
  130     (a) = ((a) + (b)) & UINT4B_MAX; \
  131 }
  132 
  133 #define GG(a, b, c, d, x, s, ac) { \
  134     (a) = ((a) + G(b, c, d) + (x) + ((ac) & UINT4B_MAX)) & UINT4B_MAX; \
  135     (a) = ROTATE_LEFT((a), (s)); \
  136     (a) = ((a) + (b)) & UINT4B_MAX; \
  137 }
  138 
  139 #define HH(a, b, c, d, x, s, ac) { \
  140     (a) = ((a) + H(b, c, d) + (x) + ((ac) & UINT4B_MAX)) & UINT4B_MAX; \
  141     (a) = ROTATE_LEFT((a), (s)); \
  142     (a) = ((a) + (b)) & UINT4B_MAX; \
  143 }
  144 
  145 #define II(a, b, c, d, x, s, ac) { \
  146     (a) = ((a) + I(b, c, d) + (x) + ((ac) & UINT4B_MAX)) & UINT4B_MAX; \
  147     (a) = ROTATE_LEFT((a), (s)); \
  148     (a) = ((a) + (b)) & UINT4B_MAX; \
  149 }
  150 
  151 static void * (* volatile _volatile_memset)(void*, int, size_t) = &(memset);
  152 
  153 static void Encode(unsigned char *outp, md5_type *inp, unsigned int len);
  154 static void Decode(md5_type *outp, unsigned char *inp, unsigned int len);
  155 static void MD5Transform(md5_type state[], unsigned char block[]);
  156 
  157 /*
  158  * Encodes input (md5_type) into output (unsigned char). Assumes len is
  159  * a multiple of 4.
  160  */
  161 static void
  162 Encode(unsigned char *outp, md5_type *inp, unsigned int len)
  163 {
  164     unsigned int i, j;
  165 
  166     for (i = 0, j = 0; j < len; i++, j += 4) {
  167         outp[j] = inp[i] & 0xff;
  168         outp[j+1] = (inp[i] >> 8) & 0xff;
  169         outp[j+2] = (inp[i] >> 16) & 0xff;
  170         outp[j+3] = (inp[i] >> 24) & 0xff;
  171     }
  172 }
  173 
  174 /*
  175  * Decodes input (unsigned char) into output (md5_type). Assumes len is
  176  * a multiple of 4.
  177  */
  178 static void
  179 Decode(md5_type *outp, unsigned char *inp, unsigned int len)
  180 {
  181     unsigned int    i, j;
  182 
  183     for (i = 0, j = 0; j < len; i++, j += 4)
  184         outp[i] = ((md5_type)inp[j] |
  185             (md5_type)inp[j+1] << 8 |
  186             (md5_type)inp[j+2] << 16 |
  187             (md5_type)inp[j+3] << 24) & UINT4B_MAX;
  188 }
  189 
  190 /* MD5 basic transformation. Transforms state based on block. */
  191 static void
  192 MD5Transform(md5_type state[4], unsigned char block[64])
  193 {
  194     md5_type a = state[0], b = state[1], c = state[2], d = state[3],
  195         x[16];
  196 
  197     Decode(x, block, 64);
  198 
  199     /* Round 1 */
  200     FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
  201     FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
  202     FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
  203     FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
  204     FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
  205     FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
  206     FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
  207     FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
  208     FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
  209     FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
  210     FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  211     FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  212     FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  213     FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  214     FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  215     FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
  216 
  217     /* Round 2 */
  218     GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
  219     GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
  220     GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  221     GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
  222     GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
  223     GG(d, a, b, c, x[10], S22,  0x2441453); /* 22 */
  224     GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  225     GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
  226     GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
  227     GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  228     GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
  229     GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
  230     GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  231     GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
  232     GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
  233     GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
  234 
  235     /* Round 3 */
  236     HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
  237     HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
  238     HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  239     HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  240     HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
  241     HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
  242     HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
  243     HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  244     HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  245     HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
  246     HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
  247     HH(b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
  248     HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
  249     HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  250     HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  251     HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
  252 
  253     /* Round 4 */
  254     II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
  255     II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
  256     II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  257     II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
  258     II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  259     II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
  260     II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  261     II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
  262     II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
  263     II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  264     II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
  265     II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  266     II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
  267     II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  268     II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
  269     II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
  270 
  271     state[0] = (state[0] + a) & UINT4B_MAX;
  272     state[1] = (state[1] + b) & UINT4B_MAX;
  273     state[2] = (state[2] + c) & UINT4B_MAX;
  274     state[3] = (state[3] + d) & UINT4B_MAX;
  275 
  276     /*
  277      * Zeroize sensitive information.
  278      */
  279     (*_volatile_memset)(x, 0, sizeof x);
  280 }
  281 
  282 /*
  283  * MD5 initialization. Begins an MD5 operation, writing a new context.
  284  */
  285 FL void
  286 md5_init(
  287     md5_ctx *context    /* context */
  288 )
  289 {
  290     context->count[0] = context->count[1] = 0;
  291     /*
  292      * Load magic initialization constants.
  293      */
  294     context->state[0] = 0x67452301;
  295     context->state[1] = 0xefcdab89;
  296     context->state[2] = 0x98badcfe;
  297     context->state[3] = 0x10325476;
  298 }
  299 
  300 /*
  301  * MD5 block update operation. Continues an MD5 message-digest
  302  * operation, processing another message block, and updating the
  303  * context.
  304  */
  305 FL void
  306 md5_update(
  307     md5_ctx *context,       /* context */
  308     unsigned char *input,       /* input block */
  309     unsigned int inputLen       /* length of input block */
  310 )
  311 {
  312     unsigned int i, idx, partLen;
  313 
  314     /* Compute number of bytes mod 64 */
  315     idx = context->count[0]>>3 & 0x3F;
  316 
  317     /* Update number of bits */
  318     if ((context->count[0] = (context->count[0] + (inputLen<<3)) &
  319                     UINT4B_MAX)
  320             < ((inputLen << 3) & UINT4B_MAX))
  321     context->count[1] = (context->count[1] + 1) & UINT4B_MAX;
  322     context->count[1] = (context->count[1] + (inputLen >> 29)) & UINT4B_MAX;
  323 
  324     partLen = 64 - idx;
  325 
  326     /*
  327      * Transform as many times as possible.
  328      */
  329     if (inputLen >= partLen) {
  330         memcpy(&context->buffer[idx], input, partLen);
  331         MD5Transform(context->state, context->buffer);
  332 
  333         for (i = partLen; i + 63 < inputLen; i += 64)
  334             MD5Transform(context->state, &input[i]);
  335 
  336         idx = 0;
  337     } else
  338         i = 0;
  339 
  340     /* Buffer remaining input */
  341     memcpy(&context->buffer[idx], &input[i], inputLen-i);
  342 }
  343 
  344 /*
  345  * MD5 finalization. Ends an MD5 message-digest operation, writing the
  346  * the message digest and zeroizing the context.
  347  */
  348 FL void
  349 md5_final(
  350     unsigned char digest[16],   /* message digest */
  351     md5_ctx *context        /* context */
  352 )
  353 {
  354     unsigned char   bits[8];
  355     unsigned int    idx, padLen;
  356 
  357     /* Save number of bits */
  358     Encode(bits, context->count, 8);
  359 
  360     /*
  361      * Pad out to 56 mod 64.
  362      */
  363     idx = context->count[0]>>3 & 0x3f;
  364     padLen = idx < 56 ? 56 - idx : 120 - idx;
  365     md5_update(context, PADDING, padLen);
  366 
  367     /* Append length (before padding) */
  368     md5_update(context, bits, 8);
  369     /* Store state in digest */
  370     Encode(digest, context->state, 16);
  371 
  372     /*
  373      * Zeroize sensitive information.
  374      */
  375     (*_volatile_memset)(context, 0, sizeof *context);
  376 }
  377 
  378 # undef UINT4B_MAX
  379 # undef S11
  380 # undef S12
  381 # undef S13
  382 # undef S14
  383 # undef S21
  384 # undef S22
  385 # undef S23
  386 # undef S24
  387 # undef S31
  388 # undef S32
  389 # undef S33
  390 # undef S34
  391 # undef S41
  392 # undef S42
  393 # undef S43
  394 # undef S44
  395 # undef F
  396 # undef G
  397 # undef H
  398 # undef I
  399 # undef ROTATE_LEFT
  400 # undef FF
  401 # undef GG
  402 # undef HH
  403 # undef II
  404 #endif /* n_MAIN_SOURCE */