sha.cpp
上传用户:ets1996
上传日期:2014-09-30
资源大小:353k
文件大小:8k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. /*_############################################################################
  2.   _## 
  3.   _##  sha.cpp  
  4.   _##
  5.   _##  SNMP++v3.2.22
  6.   _##  -----------------------------------------------
  7.   _##  Copyright (c) 2001-2007 Jochen Katz, Frank Fock
  8.   _##
  9.   _##  This software is based on SNMP++2.6 from Hewlett Packard:
  10.   _##  
  11.   _##    Copyright (c) 1996
  12.   _##    Hewlett-Packard Company
  13.   _##  
  14.   _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
  15.   _##  Permission to use, copy, modify, distribute and/or sell this software 
  16.   _##  and/or its documentation is hereby granted without fee. User agrees 
  17.   _##  to display the above copyright notice and this license notice in all 
  18.   _##  copies of the software and any documentation of the software. User 
  19.   _##  agrees to assume all liability for the use of the software; 
  20.   _##  Hewlett-Packard and Jochen Katz make no representations about the 
  21.   _##  suitability of this software for any purpose. It is provided 
  22.   _##  "AS-IS" without warranty of any kind, either express or implied. User 
  23.   _##  hereby grants a royalty-free license to any and all derivatives based
  24.   _##  upon this software code base. 
  25.   _##  
  26.   _##  Stuttgart, Germany, Wed May  2 23:22:30 CEST 2007 
  27.   _##  
  28.   _##########################################################################*/
  29. char sha_cpp_version[]="#(@) SNMP++ $Id: sha.cpp 183 2005-09-25 08:21:39Z fock $";
  30. #include "snmp_pp/sha.h"
  31. #if !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
  32. /*****************************************************************
  33.  * SHS.c  -  Secure Hash Standard (draft) FIPS 180-1             *
  34.  *                                                               *
  35.  * Copyright (C) 1994  Uri Blumenthal, uri@watson.ibm.com        *
  36.  * Copyright (C) 1994  IBM T. J. Watson esearch Center           *
  37.  *                                                               *
  38.  * Feel free to use this code,  as long as you acknowledge the   *
  39.  * ownership by U. Blumenthal and IBM Corp.  and agree to hold   *
  40.  * both harmless in case of ANY problem you may have with this   *
  41.  * code.                                                         *
  42.  *****************************************************************/
  43. #if !(defined (CPU) && CPU == PPC603)
  44. #include <memory.h>
  45. #else
  46. #include <string.h>
  47. #endif
  48. #include <stdio.h>
  49. #ifdef SNMP_PP_NAMESPACE
  50. namespace Snmp_pp {
  51. #endif
  52. #define K1 0x5A827999
  53. #define K2 0x6ED9EBA1
  54. #define K3 0x8F1BBCDC
  55. #define K4 0xCA62C1D6
  56. #define F1(B, C, D) ((B & C) | (~B & D))
  57. #define F2(B, C, D) (B ^ C ^ D)
  58. #define F3(B, C, D) ((B & C) | (B & D) | (C & D))
  59. #define F4(B, C, D) (B ^ C ^ D)
  60. #define ROL(A, K) ((A << K) | (A >> (32 - K)))
  61. #if !defined(i386) && !defined(_IBMR2)
  62. static int msb_flag = 0;    /* ENDIAN-ness of CPU    */
  63. #endif
  64. static void SHATransform(SHA_CTX *ctx, const unsigned char *X)
  65. {
  66.   unsigned /* long */ int a, b, c, d, e, temp = 0;
  67.   unsigned /* long */ int W[80]; /* Work array for SHS    */
  68.   int               i = 0;
  69. #ifdef _IBMR2
  70.     unsigned long int *p = (unsigned long int *)X;
  71.     memcpy((char *)&W[0], p, 64);
  72. #else
  73. #ifndef i386
  74.   unsigned long int *p = (unsigned long int *)X;
  75.   if (msb_flag)
  76.     memcpy((char *)&W[0], p, 64);
  77.   else
  78. #endif /* ~i386 */
  79.     for (i = 0; i < 64; i += 4)
  80.       W[(i/4)] = X[i+3] | (X[i+2] << 8) |
  81. (X[i+1] << 16) | (X[i] << 24);
  82. #endif /* _IBMR2 */
  83.   for (i = 16; i < 80; i++)
  84.     W[i] = ROL((W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]), 1);
  85.   a = ctx->h[0];
  86.   b = ctx->h[1];
  87.   c = ctx->h[2];
  88.   d = ctx->h[3];
  89.   e = ctx->h[4];
  90.   for (i =  0; i <= 19; i++) {
  91.     temp = ROL(a, 5) + F1(b, c, d) + e + K1 + W[i];
  92.     e = d; d = c; c = ROL(b, 30); b = a; a = temp;
  93.   }
  94.   for (i = 20; i <= 39; i++) {
  95.     temp = ROL(a, 5) + F2(b, c, d) + e + K2 + W[i];
  96.     e = d; d = c; c = ROL(b, 30); b = a; a = temp;
  97.   }
  98.   for (i = 40; i <= 59; i++) {
  99.     temp = ROL(a, 5) + F3(b, c, d) + e + K3 + W[i];
  100.     e = d; d = c; c = ROL(b, 30); b = a; a = temp;
  101.   }
  102.   for (i = 60; i <= 79; i++) {
  103.     temp = ROL(a, 5) + F4(b, c, d) + e + K4 + W[i];
  104.     e = d; d = c; c = ROL(b, 30); b = a; a = temp;
  105.   }
  106.   ctx->h[0] += a;
  107.   ctx->h[1] += b;
  108.   ctx->h[2] += c;
  109.   ctx->h[3] += d;
  110.   ctx->h[4] += e;
  111. }
  112. void SHAInit(SHA_CTX *ctx)
  113. {
  114. #if !defined(i386) && !defined(_IBMR2)
  115.   union z_test {
  116.     unsigned char ch[4];
  117.     unsigned long ll;
  118.   } z_t;
  119. #endif
  120.   /* Zero the SHS Context */
  121.   memset((char *)ctx, 0, sizeof(*ctx));
  122.   /* Prime the SHS with "magic" init constants */
  123.   ctx->h[0] = 0x67452301;
  124.   ctx->h[1] = 0xEFCDAB89;
  125.   ctx->h[2] = 0x98BADCFE;
  126.   ctx->h[3] = 0x10325476;
  127.   ctx->h[4] = 0xC3D2E1F0;
  128. #if !defined(i386) && !defined(_IBMR2)
  129.   /* Determine the ENDIAN-ness of the CPU */
  130.   z_t.ll = 0;
  131.   z_t.ch[0] = 0x01;
  132.   if (z_t.ll == 0x01000000)
  133.     msb_flag = 1;
  134.   else {
  135.     if (z_t.ll == 0x00000001)
  136.       msb_flag = 0;
  137.     else
  138.       printf("ENDIAN-ness is SCREWED! (%0#lx)n", z_t.ll);
  139.   }
  140. #endif /* ~_IBMR2 & ~i386 */
  141. }
  142. void SHAUpdate(SHA_CTX *ctx, const unsigned char *buf, unsigned int lenBuf)
  143. {
  144.   int i = 0;
  145.   /* Do we have any bytes? */
  146.   if (lenBuf == 0) return;
  147.   /* Calculate buf len in bits and update the len count */
  148.   ctx->count[0] += (lenBuf << 3);
  149.   if (ctx->count[0] < (lenBuf << 3))
  150.     ctx->count[1] += 1;
  151.   ctx->count[1] += (lenBuf >> 29);
  152.   /* Fill the hash working buffer for the first run, if  */
  153.   /* we have enough data...                              */
  154.   i = 64 - ctx->index;  /* either fill it up to 64 bytes */
  155.   if ((int)lenBuf < i) i = lenBuf; /* or put the whole data...*/
  156.   lenBuf -= i;  /* Reflect the data we'll put in the buf */
  157.   /* Physically put the data in the hash workbuf */
  158.   memcpy((char *)&(ctx->X[ctx->index]), buf, i);
  159.   buf += i; ctx->index += i;
  160.   /* Adjust the buf index */
  161.   if (ctx->index == 64)
  162.     ctx->index = 0;
  163.   /* Let's see whether we're equal to 64 bytes in buf  */
  164.   if (ctx->index == 0)
  165.     SHATransform(ctx, ctx->X);
  166.   /* Process full 64-byte blocks */
  167.   while(lenBuf >= 64) {
  168.     lenBuf -= 64;
  169.     SHATransform(ctx, buf);
  170.     buf += 64;
  171.   }
  172.   /* Put the rest of data in the hash buf for next run */
  173.   if (lenBuf > 0) {
  174.     memcpy(ctx->X, buf, lenBuf);
  175.     ctx->index = lenBuf;
  176.   }
  177. }
  178. void SHAFinal(unsigned char *digest, SHA_CTX *ctx)
  179. {
  180.   int i;
  181.   unsigned long int c0, c1;
  182.   unsigned char truelen[8];
  183.   static unsigned char padding[64] = {
  184.     0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /*  8 */
  185.     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 16 */
  186.     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 24 */
  187.     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 32 */
  188.     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 40 */
  189.     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 48 */
  190.     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  /* 56 */
  191.     0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; /* 64 */
  192.   /* Store the message length to append after */
  193.   /* padding is done... */
  194. #ifdef _IBMR2
  195.     memcpy(truelen, (char *) &(ctx->count[1]), 4);
  196.     memcpy(&truelen[4], (char *) &(ctx->count[0]), 4);
  197. #else
  198. #ifndef i386
  199.   if (msb_flag) {
  200.     memcpy(truelen, (char *) &(ctx->count[1]), 4);
  201.     memcpy(&truelen[4], (char *) &(ctx->count[0]), 4);
  202.   } else
  203. #endif /* ~i386 */
  204.   {
  205.     c0 = ctx->count[0]; c1 = ctx->count[1];
  206.     for (i = 7; i >=0; i--) {
  207.       truelen[i] = (unsigned char) (c0 & 0xff);
  208.       c0 = (c0 >> 8) | (((c1 >> 8) & 0xff) << 24);
  209.       c1 = (c1 >> 8);
  210.     }
  211.   }
  212. #endif /* _IBMR2 */
  213.   /* How many padding bytes do we need? */
  214.   i = (ctx->count[0] >> 3) & 0x3f;  /* # of bytes mod 64 */
  215.   if (i >= 56) i = 120 - i; /* # of padding bytes needed */
  216.   else i = 56 - i;
  217.   SHAUpdate(ctx, padding, i);   /* Append the padding */
  218.   SHAUpdate(ctx, truelen, 8);   /* Append the length  */
  219. #ifdef _IBMR2
  220.     memcpy(digest, (char *)&ctx->h[0], 20);
  221. #else
  222. #ifndef i386
  223.   if (msb_flag)
  224.     memcpy(digest, (char *)&ctx->h[0], 20);
  225.   else
  226. #endif /* ~i386 */
  227.     for (i = 0; i < 4; i++) {
  228.       digest[3-i]  = (unsigned char) (ctx->h[0] & 0xff);
  229.       ctx->h[0] >>= 8;
  230.       digest[7-i]  = (unsigned char) (ctx->h[1] & 0xff);
  231.       ctx->h[1] >>= 8;
  232.       digest[11-i] = (unsigned char) (ctx->h[2] & 0xff);
  233.       ctx->h[2] >>= 8;
  234.       digest[15-i] = (unsigned char) (ctx->h[3] & 0xff);
  235.       ctx->h[3] >>= 8;
  236.       digest[19-i] = (unsigned char) (ctx->h[4] & 0xff);
  237.       ctx->h[4] >>= 8;
  238.     }
  239. #endif /* _IBMR2 */
  240. }
  241. #ifdef SNMP_PP_NAMESPACE
  242. }; // end of namespace Snmp_pp
  243. #endif 
  244. #endif // !defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)