Sha2.hpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
00014 
00015 //----------------------------------------------------------------------
00022 //----------------------------------------------------------------------
00023 #ifndef ICL_CORE_CRYPT_SHA2_HPP_INCLUDED
00024 #define ICL_CORE_CRYPT_SHA2_HPP_INCLUDED
00025 
00026 #include <sstream>
00027 #include <iomanip>
00028 #include <string.h>
00029 
00030 namespace icl_core {
00031 namespace crypt {
00032 
00033 #define TEMPLATEM template <typename T, T t_h0, T t_h1, T t_h2, T t_h3, T t_h4, T t_h5, T t_h6, T t_h7, size_t t_len>
00034 #define CLASSM Sha2<T, t_h0, t_h1, t_h2, t_h3, t_h4, t_h5, t_h6, t_h7, t_len>
00035 #define IMPLM Sha2Impl<T, t_h0, t_h1, t_h2, t_h3, t_h4, t_h5, t_h6, t_h7, t_len>
00036 
00037 TEMPLATEM
00038 CLASSM::Sha2()
00039   : IMPLM()
00040 {
00041 }
00042 
00043 TEMPLATEM
00044 CLASSM& CLASSM::process(const char *data)
00045 {
00046   for (; *data != 0; ++data)
00047   {
00048     if (m_buffer_fill == cMESSAGE_BLOCK_SIZE)
00049     {
00050       processBuffer();
00051       m_buffer_fill = 0;
00052     }
00053     m_buffer[m_buffer_fill++] = *data;
00054     ++m_message_size;
00055   }
00056   return *this;
00057 }
00058 
00059 TEMPLATEM
00060 CLASSM& CLASSM::process(const void *data, size_t size)
00061 {
00062   const uint8_t *ptr = reinterpret_cast<const uint8_t *>(data);
00063   size_t rest = size;
00064 
00065   // Fill the buffer completely as many times as possible.
00066   while (rest >= cMESSAGE_BLOCK_SIZE-m_buffer_fill)
00067   {
00068     size_t amount = cMESSAGE_BLOCK_SIZE-m_buffer_fill;
00069     ::memcpy(&m_buffer[m_buffer_fill], ptr, amount);
00070     rest -= amount;
00071     processBuffer();
00072     ptr += amount;
00073     m_message_size += amount;
00074     m_buffer_fill = 0;
00075   }
00076   // Partially fill the buffer using the remaining data.
00077   ::memcpy(&m_buffer[m_buffer_fill], ptr, rest);
00078   m_message_size += rest;
00079   m_buffer_fill += rest;
00080   return *this;
00081 }
00082 
00083 TEMPLATEM
00084 CLASSM& CLASSM::finalize()
00085 {
00086   finalizeBuffer(m_buffer_fill);
00087   return *this;
00088 }
00089 
00090 #define bswap64(i) ((i) >> 56 |                                 \
00091                     (((i) >> 40) & 0x000000000000ff00ull) |     \
00092                     (((i) >> 24) & 0x0000000000ff0000ull) |     \
00093                     (((i) >>  8) & 0x00000000ff000000ull) |     \
00094                     (((i) <<  8) & 0x000000ff00000000ull) |     \
00095                     (((i) << 24) & 0x0000ff0000000000ull) |     \
00096                     (((i) << 40) & 0x00ff000000000000ull) |     \
00097                     (i) << 56)                                  \
00098 
00099 TEMPLATEM
00100 void CLASSM::finalizeBuffer(size_t size)
00101 {
00102   uint64_t message_size_bits = m_message_size*8;
00103 
00104   // Always pad a "1" bit (i.e., 0x80).
00105   if (size < cMESSAGE_BLOCK_SIZE)
00106   {
00107     m_buffer[size++] = 0x80;
00108   }
00109   else
00110   {
00111     // Buffer is full, process first and then add the 0x80
00112     processBuffer();
00113     m_buffer[0] = 0x80;
00114     size = 1;
00115   }
00116 
00117   // Now pad to the padding position.
00118   if (size <= cMESSAGE_PAD_POSITION)
00119   {
00120     for (size_t i = size; i < cMESSAGE_BLOCK_SIZE-8; ++i)
00121     {
00122       m_buffer[i] = 0;
00123     }
00124     m_buffer[cMESSAGE_BLOCK_SIZE-8] = uint8_t((message_size_bits >> 56) & 0xff);
00125     m_buffer[cMESSAGE_BLOCK_SIZE-7] = uint8_t((message_size_bits >> 48) & 0xff);
00126     m_buffer[cMESSAGE_BLOCK_SIZE-6] = uint8_t((message_size_bits >> 40) & 0xff);
00127     m_buffer[cMESSAGE_BLOCK_SIZE-5] = uint8_t((message_size_bits >> 32) & 0xff);
00128     m_buffer[cMESSAGE_BLOCK_SIZE-4] = uint8_t((message_size_bits >> 24) & 0xff);
00129     m_buffer[cMESSAGE_BLOCK_SIZE-3] = uint8_t((message_size_bits >> 16) & 0xff);
00130     m_buffer[cMESSAGE_BLOCK_SIZE-2] = uint8_t((message_size_bits >>  8) & 0xff);
00131     m_buffer[cMESSAGE_BLOCK_SIZE-1] = uint8_t((message_size_bits      ) & 0xff);
00132     processBuffer();
00133   }
00134   else
00135   {
00136     // Pad buffer first and process.  The message size goes into the
00137     // next block.
00138     for (size_t i = size; i < cMESSAGE_BLOCK_SIZE; ++i)
00139     {
00140       m_buffer[i] = 0;
00141     }
00142     processBuffer();
00143 
00144     // Pad the next block.
00145     for (size_t i = 0; i < cMESSAGE_BLOCK_SIZE-8; ++i)
00146     {
00147       m_buffer[i] = 0;
00148     }
00149     m_buffer[cMESSAGE_BLOCK_SIZE-8] = uint8_t((message_size_bits >> 56) & 0xff);
00150     m_buffer[cMESSAGE_BLOCK_SIZE-7] = uint8_t((message_size_bits >> 48) & 0xff);
00151     m_buffer[cMESSAGE_BLOCK_SIZE-6] = uint8_t((message_size_bits >> 40) & 0xff);
00152     m_buffer[cMESSAGE_BLOCK_SIZE-5] = uint8_t((message_size_bits >> 32) & 0xff);
00153     m_buffer[cMESSAGE_BLOCK_SIZE-4] = uint8_t((message_size_bits >> 24) & 0xff);
00154     m_buffer[cMESSAGE_BLOCK_SIZE-3] = uint8_t((message_size_bits >> 16) & 0xff);
00155     m_buffer[cMESSAGE_BLOCK_SIZE-2] = uint8_t((message_size_bits >>  8) & 0xff);
00156     m_buffer[cMESSAGE_BLOCK_SIZE-1] = uint8_t((message_size_bits      ) & 0xff);
00157     processBuffer();
00158   }
00159 }
00160 
00161 #undef bswap64
00162 
00163 #undef TEMPLATEM
00164 #undef CLASSM
00165 #undef IMPLM
00166 
00167 }
00168 }
00169 
00170 #endif


fzi_icl_core
Author(s):
autogenerated on Tue Aug 8 2017 02:28:04