crypto
Published 29 Dec 2009, by
Anders Rundgren

No tags
« Back to documentation index
Show/hide line numbers
SHACore.cpp Source File
SHACore.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <string.h>
00014 #include <stdlib.h>
00015
00016 #include "crypto.h"
00017
00018 #include "_shacommon.h"
00019
00020 namespace webpki
00021 {
00022
00023 const int SHACore::SHA_LBLOCK;
00024
00025 const int SHACore::SHA_CBLOCK;
00026
00027
00028 const char* SHACore::doFinal (unsigned char* digest, const unsigned char* data, int length)
00029 {
00030 update (data, length);
00031 return doFinal (digest);
00032 }
00033
00034
00035 void SHACore::update (const unsigned char* data, int data_length)
00036 {
00037 unsigned char *p;
00038 CRYPTO_U32 l;
00039 int n;
00040
00041 if (m_needs_init)
00042 {
00043 _init ();
00044 }
00045
00046 if (data_length == 0) return;
00047
00048 l = (m_sha_ctx.Nl + (((CRYPTO_U32)data_length)<<3))&0xffffffffUL;
00049
00050
00051 if (l < m_sha_ctx.Nl)
00052 {
00053 m_sha_ctx.Nh++;
00054 }
00055 m_sha_ctx.Nh += (data_length >> 29);
00056 m_sha_ctx.Nl = l;
00057
00058 n = m_sha_ctx.num;
00059 if (n != 0)
00060 {
00061 p = (unsigned char*) m_sha_ctx.data;
00062
00063 if (data_length >= SHA_CBLOCK || data_length + n >= SHA_CBLOCK)
00064 {
00065 memcpy (p + n, data, SHA_CBLOCK - n);
00066 hash_block_data_order (p, 1);
00067 n = SHA_CBLOCK - n;
00068 data += n;
00069 data_length -= n;
00070 m_sha_ctx.num = 0;
00071 memset (p, 0, SHA_CBLOCK);
00072 }
00073 else
00074 {
00075 memcpy (p+n, data, data_length);
00076 m_sha_ctx.num += (unsigned int)data_length;
00077 return;
00078 }
00079 }
00080
00081 n = data_length / SHA_CBLOCK;
00082 if (n > 0)
00083 {
00084 hash_block_data_order (data, n);
00085 n *= SHA_CBLOCK;
00086 data += n;
00087 data_length -= n;
00088 }
00089
00090 if (data_length)
00091 {
00092 p = (unsigned char *)m_sha_ctx.data;
00093 m_sha_ctx.num = data_length;
00094 memcpy (p, data, data_length);
00095 }
00096 }
00097
00098
00099 const char* SHACore::doFinal (unsigned char* out)
00100 {
00101 m_needs_init = true;
00102 if (m_error)
00103 {
00104 return m_error;
00105 }
00106 unsigned char *p = (unsigned char *)m_sha_ctx.data;
00107 int n = m_sha_ctx.num;
00108
00109 p[n] = 0x80;
00110 n++;
00111
00112 if (n > (SHA_CBLOCK - 8))
00113 {
00114 memset (p+n, 0, SHA_CBLOCK - n);
00115 n = 0;
00116 hash_block_data_order (p,1);
00117 }
00118 memset (p+n, 0, SHA_CBLOCK - 8 - n);
00119
00120 p += SHA_CBLOCK - 8;
00121 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
00122 (void)HOST_l2c(m_sha_ctx.Nh, p);
00123 (void)HOST_l2c(m_sha_ctx.Nl, p);
00124 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
00125 (void)HOST_l2c(m_sha_ctx.Nl, p);
00126 (void)HOST_l2c(m_sha_ctx.Nh, p);
00127 #endif
00128 p -= SHA_CBLOCK;
00129 hash_block_data_order (p,1);
00130 m_sha_ctx.num = 0;
00131 memset (p, 0, SHA_CBLOCK);
00132
00133 for (int xn = 0; xn < m_sha_ctx.digest_length/4; xn++)
00134 {
00135 CRYPTO_U32 ll = m_sha_ctx.h[xn]; HOST_l2c(ll,(out));
00136 }
00137 return m_error;
00138 }
00139
00140
00141 }