(root)/
Linux-PAM-1.5.3/
modules/
pam_timestamp/
sha1.c
       1  /* Yet another SHA-1 implementation.
       2   *
       3   * Copyright (c) 2003 Red Hat, Inc.
       4   * Written by Nalin Dahyabhai <nalin@redhat.com>
       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, and the entire permission notice in its entirety,
      11   *    including the disclaimer of warranties.
      12   * 2. Redistributions in binary form must reproduce the above copyright
      13   *    notice, this list of conditions and the following disclaimer in the
      14   *    documentation and/or other materials provided with the distribution.
      15   * 3. The name of the author may not be used to endorse or promote
      16   *    products derived from this software without specific prior
      17   *    written permission.
      18   *
      19   * ALTERNATIVELY, this product may be distributed under the terms of
      20   * the GNU Public License, in which case the provisions of the GPL are
      21   * required INSTEAD OF the above restrictions.  (This clause is
      22   * necessary due to a potential bad interaction between the GPL and
      23   * the restrictions contained in a BSD-style copyright.)
      24   *
      25   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
      26   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      27   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      28   * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
      29   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      30   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      31   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      32   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      33   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      34   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      35   * OF THE POSSIBILITY OF SUCH DAMAGE.
      36   *
      37   */
      38  /* See http://www.itl.nist.gov/fipspubs/fip180-1.htm for descriptions. */
      39  
      40  #include <sys/types.h>
      41  #include <sys/stat.h>
      42  #include <netinet/in.h>
      43  #include <fcntl.h>
      44  #include <stdio.h>
      45  #include <stdlib.h>
      46  #include <string.h>
      47  #include <endian.h>
      48  #include <unistd.h>
      49  #include "sha1.h"
      50  
      51  static unsigned char
      52  padding[SHA1_BLOCK_SIZE] = {
      53  	0x80, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
      54  	   0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
      55  	   0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
      56  	   0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
      57  };
      58  
      59  static uint32_t
      60  F(uint32_t b, uint32_t c, uint32_t d)
      61  {
      62  	return (b & c) | ((~b) & d);
      63  }
      64  
      65  static uint32_t
      66  G(uint32_t b, uint32_t c, uint32_t d)
      67  {
      68  	return b ^ c ^ d;
      69  }
      70  
      71  static uint32_t
      72  H(uint32_t b, uint32_t c, uint32_t d)
      73  {
      74  	return (b & c) | (b & d) | (c & d);
      75  }
      76  
      77  static uint32_t
      78  RL(uint32_t n, uint32_t s)
      79  {
      80  	return (n << s) | (n >> (32 - s));
      81  }
      82  
      83  static uint32_t
      84  sha1_round(uint32_t (*FUNC)(uint32_t, uint32_t, uint32_t),
      85        uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
      86        uint32_t i, uint32_t n)
      87  {
      88  	return RL(a, 5) + FUNC(b, c, d) + e + i + n;
      89  }
      90  
      91  void
      92  sha1_init(struct sha1_context *ctx)
      93  {
      94  	memset(ctx, 0, sizeof(*ctx));
      95  	ctx->a = 0x67452301;
      96  	ctx->b = 0xefcdab89;
      97  	ctx->c = 0x98badcfe;
      98  	ctx->d = 0x10325476;
      99  	ctx->e = 0xc3d2e1f0;
     100  }
     101  
     102  static void
     103  sha1_process(struct sha1_context *ctx, uint32_t buffer[SHA1_BLOCK_SIZE / 4])
     104  {
     105  	uint32_t a, b, c, d, e, temp;
     106  	uint32_t data[80];
     107  	int i;
     108  
     109  	for (i = 0; i < 16; i++) {
     110  		data[i] = htonl(buffer[i]);
     111  	}
     112  	for (i = 16; i < 80; i++) {
     113  		data[i] = RL(data[i - 3] ^ data[i - 8] ^ data[i - 14] ^ data[i - 16], 1);
     114  	}
     115  
     116  	a = ctx->a;
     117  	b = ctx->b;
     118  	c = ctx->c;
     119  	d = ctx->d;
     120  	e = ctx->e;
     121  
     122  	for (i =  0; i < 20; i++) {
     123  		temp = sha1_round(F, a, b, c, d, e, data[i], 0x5a827999);
     124  		e = d; d = c; c = RL(b, 30); b = a; a = temp;
     125  	}
     126  	for (i = 20; i < 40; i++) {
     127  		temp = sha1_round(G, a, b, c, d, e, data[i], 0x6ed9eba1);
     128  		e = d; d = c; c = RL(b, 30); b = a; a = temp;
     129  	}
     130  	for (i = 40; i < 60; i++) {
     131  		temp = sha1_round(H, a, b, c, d, e, data[i], 0x8f1bbcdc);
     132  		e = d; d = c; c = RL(b, 30); b = a; a = temp;
     133  	}
     134  	for (i = 60; i < 80; i++) {
     135  		temp = sha1_round(G, a, b, c, d, e, data[i], 0xca62c1d6);
     136  		e = d; d = c; c = RL(b, 30); b = a; a = temp;
     137  	}
     138  
     139  	ctx->a += a;
     140  	ctx->b += b;
     141  	ctx->c += c;
     142  	ctx->d += d;
     143  	ctx->e += e;
     144  
     145  	memset(buffer, 0, sizeof(buffer[0]) * SHA1_BLOCK_SIZE / 4);
     146  	memset(data, 0, sizeof(data));
     147  }
     148  
     149  void
     150  sha1_update(struct sha1_context *ctx, const unsigned char *data, size_t length)
     151  {
     152  	size_t i = 0, l = length, c, t;
     153  	uint32_t count = 0;
     154  
     155  	/* Process any pending + data blocks. */
     156  	while (l + ctx->pending_count >= SHA1_BLOCK_SIZE) {
     157  		c = ctx->pending_count;
     158  		t = SHA1_BLOCK_SIZE - c;
     159  		memcpy(ctx->pending.c + c, &data[i], t);
     160  		sha1_process(ctx, ctx->pending.i);
     161  		i += t;
     162  		l -= t;
     163  		ctx->pending_count = 0;
     164  	}
     165  
     166  	/* Save what's left of the data block as a pending data block. */
     167  	c = ctx->pending_count;
     168  	memcpy(ctx->pending.c + c, &data[i], l);
     169  	ctx->pending_count += l;
     170  
     171  	/* Update the message length. */
     172  	ctx->count += length;
     173  
     174  	/* Update our internal counts. */
     175  	if (length != 0) {
     176  		count = ctx->counts[0];
     177  		ctx->counts[0] += length;
     178  		if (count >= ctx->counts[0]) {
     179  			ctx->counts[1]++;
     180  		}
     181  	}
     182  }
     183  
     184  size_t
     185  sha1_output(struct sha1_context *ctx, unsigned char *out)
     186  {
     187  	struct sha1_context ctx2;
     188  
     189  	/* Output the sum. */
     190  	if (out != NULL) {
     191  		uint32_t c;
     192  		memcpy(&ctx2, ctx, sizeof(ctx2));
     193  
     194  		/* Pad this block. */
     195  		c = ctx2.pending_count;
     196  		memcpy(ctx2.pending.c + c,
     197  		       padding, SHA1_BLOCK_SIZE - c);
     198  
     199  		/* Do we need to process two blocks now? */
     200  		if (c >= (SHA1_BLOCK_SIZE - (sizeof(uint32_t) * 2))) {
     201  			/* Process this block. */
     202  			sha1_process(&ctx2, ctx2.pending.i);
     203  			/* Set up another block. */
     204  			ctx2.pending_count = 0;
     205  			memset(ctx2.pending.c, 0, SHA1_BLOCK_SIZE);
     206                          ctx2.pending.c[0] =
     207  				(c == SHA1_BLOCK_SIZE) ? 0x80 : 0;
     208  		}
     209  
     210  		/* Process the final block. */
     211  		ctx2.counts[1] <<= 3;
     212  		if (ctx2.counts[0] >> 29) {
     213  			ctx2.counts[1] |=
     214  			(ctx2.counts[0] >> 29);
     215  		}
     216  		ctx2.counts[0] <<= 3;
     217  		ctx2.counts[0] = htonl(ctx2.counts[0]);
     218  		ctx2.counts[1] = htonl(ctx2.counts[1]);
     219  		memcpy(ctx2.pending.c + 56,
     220  		       &ctx2.counts[1], sizeof(uint32_t));
     221  		memcpy(ctx2.pending.c + 60,
     222  		       &ctx2.counts[0], sizeof(uint32_t));
     223  		sha1_process(&ctx2, ctx2.pending.i);
     224  
     225  		/* Output the data. */
     226  		out[ 3] = (ctx2.a >>  0) & 0xff;
     227  		out[ 2] = (ctx2.a >>  8) & 0xff;
     228  		out[ 1] = (ctx2.a >> 16) & 0xff;
     229  		out[ 0] = (ctx2.a >> 24) & 0xff;
     230  
     231  		out[ 7] = (ctx2.b >>  0) & 0xff;
     232  		out[ 6] = (ctx2.b >>  8) & 0xff;
     233  		out[ 5] = (ctx2.b >> 16) & 0xff;
     234  		out[ 4] = (ctx2.b >> 24) & 0xff;
     235  
     236  		out[11] = (ctx2.c >>  0) & 0xff;
     237  		out[10] = (ctx2.c >>  8) & 0xff;
     238  		out[ 9] = (ctx2.c >> 16) & 0xff;
     239  		out[ 8] = (ctx2.c >> 24) & 0xff;
     240  
     241  		out[15] = (ctx2.d >>  0) & 0xff;
     242  		out[14] = (ctx2.d >>  8) & 0xff;
     243  		out[13] = (ctx2.d >> 16) & 0xff;
     244  		out[12] = (ctx2.d >> 24) & 0xff;
     245  
     246  		out[19] = (ctx2.e >>  0) & 0xff;
     247  		out[18] = (ctx2.e >>  8) & 0xff;
     248  		out[17] = (ctx2.e >> 16) & 0xff;
     249  		out[16] = (ctx2.e >> 24) & 0xff;
     250  	}
     251  
     252  	return SHA1_OUTPUT_SIZE;
     253  }