Search Code
About crypto

Published 29 Dec 2009.

Last change message: N/A

Import this program

crypto

Published 29 Dec 2009, by   user Anders Rundgren   tag No tags
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHACore.cpp Source File

SHACore.cpp

00001 /* ====================================================================
00002  * Copyright (c) 1998-2010 The OpenSSL Project.  All rights reserved.
00003  *
00004  * This product includes cryptographic software written by Eric Young
00005  * (eay@cryptsoft.com).  This product includes software written by Tim
00006  * Hudson (tjh@cryptsoft.com).
00007  *
00008  * ====================================================================
00009  * C++ adoption was made by Anders Rundgren (anders.rundgren@telia.com)
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     /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
00050      * Wei Dai <weidai@eskimo.com> for pointing it out. */
00051     if (l < m_sha_ctx.Nl) /* overflow */
00052       {
00053         m_sha_ctx.Nh++;
00054       }
00055     m_sha_ctx.Nh += (data_length >> 29);   /* might cause compiler warning on 16-bit */
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);   /* keep it zeroed */
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; /* there is always room for one */
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 }