root/maint/gnulib/lib/md2.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. md2_init_ctx
  2. md2_read_ctx
  3. md2_finish_ctx
  4. md2_buffer
  5. md2_process_bytes
  6. md2_update_chksum
  7. md2_compress
  8. md2_process_block

   1 /* Functions to compute MD2 message digest of files or memory blocks.
   2    according to the definition of MD2 in RFC 1319 from April 1992.
   3    Copyright (C) 1995-1997, 1999-2003, 2005-2006, 2008-2021 Free Software
   4    Foundation, Inc.
   5 
   6    This file is free software: you can redistribute it and/or modify
   7    it under the terms of the GNU Lesser General Public License as
   8    published by the Free Software Foundation; either version 2.1 of the
   9    License, or (at your option) any later version.
  10 
  11    This file is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU Lesser General Public License for more details.
  15 
  16    You should have received a copy of the GNU Lesser General Public License
  17    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  18 
  19 /* Adapted by Simon Josefsson from public domain Libtomcrypt 1.06 by
  20    Tom St Denis. */
  21 
  22 #include <config.h>
  23 
  24 /* Specification.  */
  25 #include "md2.h"
  26 
  27 #include <string.h>
  28 #include <sys/types.h>
  29 
  30 #include <minmax.h>
  31 
  32 static void md2_update_chksum (struct md2_ctx *md);
  33 static void md2_compress (struct md2_ctx *md);
  34 
  35 /* Initialize structure containing state of computation.
  36    (RFC 1319, 3.3: Step 3)  */
  37 void
  38 md2_init_ctx (struct md2_ctx *ctx)
     /* [previous][next][first][last][top][bottom][index][help] */
  39 {
  40   memset (ctx->X, 0, sizeof (ctx->X));
  41   memset (ctx->chksum, 0, sizeof (ctx->chksum));
  42   memset (ctx->buf, 0, sizeof (ctx->buf));
  43   ctx->curlen = 0;
  44 }
  45 
  46 /* Put result from CTX in first 16 bytes following RESBUF.  The result
  47    must be in little endian byte order.  */
  48 void *
  49 md2_read_ctx (const struct md2_ctx *ctx, void *resbuf)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51   memcpy (resbuf, ctx->X, 16);
  52 
  53   return resbuf;
  54 }
  55 
  56 /* Process the remaining bytes in the internal buffer and the usual
  57    prolog according to the standard and write the result to RESBUF.  */
  58 void *
  59 md2_finish_ctx (struct md2_ctx *ctx, void *resbuf)
     /* [previous][next][first][last][top][bottom][index][help] */
  60 {
  61   unsigned long i, k;
  62 
  63   /* pad the message */
  64   k = 16 - ctx->curlen;
  65   for (i = ctx->curlen; i < 16; i++)
  66     {
  67       ctx->buf[i] = (unsigned char) k;
  68     }
  69 
  70   /* hash and update */
  71   md2_compress (ctx);
  72   md2_update_chksum (ctx);
  73 
  74   /* hash checksum */
  75   memcpy (ctx->buf, ctx->chksum, 16);
  76   md2_compress (ctx);
  77 
  78   return md2_read_ctx (ctx, resbuf);
  79 }
  80 
  81 /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
  82    result is always in little endian byte order, so that a byte-wise
  83    output yields to the wanted ASCII representation of the message
  84    digest.  */
  85 void *
  86 md2_buffer (const char *buffer, size_t len, void *resblock)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88   struct md2_ctx ctx;
  89 
  90   /* Initialize the computation context.  */
  91   md2_init_ctx (&ctx);
  92 
  93   /* Process whole buffer but last len % 64 bytes.  */
  94   md2_process_block (buffer, len, &ctx);
  95 
  96   /* Put result in desired memory area.  */
  97   return md2_finish_ctx (&ctx, resblock);
  98 }
  99 
 100 void
 101 md2_process_bytes (const void *buffer, size_t len, struct md2_ctx *ctx)
     /* [previous][next][first][last][top][bottom][index][help] */
 102 {
 103   const char *in = buffer;
 104   unsigned long n;
 105 
 106   while (len > 0)
 107     {
 108       n = MIN (len, (16 - ctx->curlen));
 109       memcpy (ctx->buf + ctx->curlen, in, (size_t) n);
 110       ctx->curlen += n;
 111       in += n;
 112       len -= n;
 113 
 114       /* is 16 bytes full? */
 115       if (ctx->curlen == 16)
 116         {
 117           md2_compress (ctx);
 118           md2_update_chksum (ctx);
 119           ctx->curlen = 0;
 120         }
 121     }
 122 }
 123 
 124 static const unsigned char PI_SUBST[256] = {
 125   41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
 126   19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
 127   76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
 128   138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
 129   245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
 130   148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
 131   39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
 132   181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
 133   150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
 134   112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
 135   96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
 136   85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
 137   234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
 138   129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
 139   8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
 140   203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
 141   166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
 142   31, 26, 219, 153, 141, 51, 159, 17, 131, 20
 143 };
 144 
 145 /* adds 16 bytes to the checksum */
 146 static void
 147 md2_update_chksum (struct md2_ctx *ctx)
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149   int j;
 150   unsigned char L;
 151 
 152   L = ctx->chksum[15];
 153   for (j = 0; j < 16; j++)
 154     {
 155       /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the
 156          reference source code [and test vectors] say otherwise. */
 157       L = (ctx->chksum[j] ^= PI_SUBST[(int) (ctx->buf[j] ^ L)] & 255);
 158     }
 159 }
 160 
 161 static void
 162 md2_compress (struct md2_ctx *ctx)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164   size_t j, k;
 165   unsigned char t;
 166 
 167   /* copy block */
 168   for (j = 0; j < 16; j++)
 169     {
 170       ctx->X[16 + j] = ctx->buf[j];
 171       ctx->X[32 + j] = ctx->X[j] ^ ctx->X[16 + j];
 172     }
 173 
 174   t = (unsigned char) 0;
 175 
 176   /* do 18 rounds */
 177   for (j = 0; j < 18; j++)
 178     {
 179       for (k = 0; k < 48; k++)
 180         {
 181           t = (ctx->X[k] ^= PI_SUBST[(int) (t & 255)]);
 182         }
 183       t = (t + (unsigned char) j) & 255;
 184     }
 185 }
 186 
 187 /* Process LEN bytes of BUFFER, accumulating context into CTX.  */
 188 void
 189 md2_process_block (const void *buffer, size_t len, struct md2_ctx *ctx)
     /* [previous][next][first][last][top][bottom][index][help] */
 190 {
 191   md2_process_bytes (buffer, len, ctx);
 192 }

/* [previous][next][first][last][top][bottom][index][help] */