00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "inspircd.h"
00054 #ifdef HAS_STDINT
00055 #include <stdint.h>
00056 #endif
00057 #include "m_hash.h"
00058
00059 #ifndef HAS_STDINT
00060 typedef unsigned int uint32_t;
00061 #endif
00062
00065 class SHA256Context : public classbase
00066 {
00067 public:
00068 unsigned int tot_len;
00069 unsigned int len;
00070 unsigned char block[2 * SHA256_BLOCK_SIZE];
00071 uint32_t h[8];
00072 };
00073
00074 #define SHFR(x, n) (x >> n)
00075 #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
00076 #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n)))
00077 #define CH(x, y, z) ((x & y) ^ (~x & z))
00078 #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
00079
00080 #define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
00081 #define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
00082 #define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3))
00083 #define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
00084
00085 #define UNPACK32(x, str) \
00086 { \
00087 *((str) + 3) = (uint8_t) ((x) ); \
00088 *((str) + 2) = (uint8_t) ((x) >> 8); \
00089 *((str) + 1) = (uint8_t) ((x) >> 16); \
00090 *((str) + 0) = (uint8_t) ((x) >> 24); \
00091 }
00092
00093 #define PACK32(str, x) \
00094 { \
00095 *(x) = ((uint32_t) *((str) + 3) ) \
00096 | ((uint32_t) *((str) + 2) << 8) \
00097 | ((uint32_t) *((str) + 1) << 16) \
00098 | ((uint32_t) *((str) + 0) << 24); \
00099 }
00100
00101
00102
00103 #define SHA256_SCR(i) \
00104 { \
00105 w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \
00106 + SHA256_F3(w[i - 15]) + w[i - 16]; \
00107 }
00108
00109 const unsigned int sha256_h0[8] =
00110 {
00111 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
00112 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
00113 };
00114
00115 uint32_t sha256_k[64] =
00116 {
00117 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
00118 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00119 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
00120 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00121 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00122 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00123 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
00124 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00125 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
00126 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00127 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
00128 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00129 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
00130 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00131 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00132 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00133 };
00134
00135 class ModuleSHA256 : public Module
00136 {
00137 void SHA256Init(SHA256Context *ctx, const unsigned int* ikey)
00138 {
00139 if (ikey)
00140 {
00141 for (int i = 0; i < 8; i++)
00142 ctx->h[i] = ikey[i];
00143 }
00144 else
00145 {
00146 for (int i = 0; i < 8; i++)
00147 ctx->h[i] = sha256_h0[i];
00148 }
00149 ctx->len = 0;
00150 ctx->tot_len = 0;
00151 }
00152
00153 void SHA256Transform(SHA256Context *ctx, unsigned char *message, unsigned int block_nb)
00154 {
00155 uint32_t w[64];
00156 uint32_t wv[8];
00157 unsigned char *sub_block;
00158 for (unsigned int i = 1; i <= block_nb; i++)
00159 {
00160 int j;
00161 sub_block = message + ((i - 1) << 6);
00162
00163 for (j = 0; j < 16; j++)
00164 PACK32(&sub_block[j << 2], &w[j]);
00165 for (j = 16; j < 64; j++)
00166 SHA256_SCR(j);
00167 for (j = 0; j < 8; j++)
00168 wv[j] = ctx->h[j];
00169 for (j = 0; j < 64; j++)
00170 {
00171 uint32_t t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) + sha256_k[j] + w[j];
00172 uint32_t t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
00173 wv[7] = wv[6];
00174 wv[6] = wv[5];
00175 wv[5] = wv[4];
00176 wv[4] = wv[3] + t1;
00177 wv[3] = wv[2];
00178 wv[2] = wv[1];
00179 wv[1] = wv[0];
00180 wv[0] = t1 + t2;
00181 }
00182 for (j = 0; j < 8; j++)
00183 ctx->h[j] += wv[j];
00184 }
00185 }
00186
00187 void SHA256Update(SHA256Context *ctx, unsigned char *message, unsigned int len)
00188 {
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 unsigned int tmp_len = SHA256_BLOCK_SIZE - ctx->len;
00206 unsigned int rem_len = len < tmp_len ? len : tmp_len;
00207
00208
00209 memcpy(&ctx->block[ctx->len], message, rem_len);
00210 if (ctx->len + len < SHA256_BLOCK_SIZE)
00211 {
00212 ctx->len += len;
00213 return;
00214 }
00215 unsigned int new_len = len - rem_len;
00216 unsigned int block_nb = new_len / SHA256_BLOCK_SIZE;
00217 unsigned char *shifted_message = message + rem_len;
00218 SHA256Transform(ctx, ctx->block, 1);
00219 SHA256Transform(ctx, shifted_message, block_nb);
00220 rem_len = new_len % SHA256_BLOCK_SIZE;
00221 memcpy(ctx->block, &shifted_message[block_nb << 6],rem_len);
00222 ctx->len = rem_len;
00223 ctx->tot_len += (block_nb + 1) << 6;
00224 }
00225
00226 void SHA256Final(SHA256Context *ctx, unsigned char *digest)
00227 {
00228 unsigned int block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) < (ctx->len % SHA256_BLOCK_SIZE)));
00229 unsigned int len_b = (ctx->tot_len + ctx->len) << 3;
00230 unsigned int pm_len = block_nb << 6;
00231 memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
00232 ctx->block[ctx->len] = 0x80;
00233 UNPACK32(len_b, ctx->block + pm_len - 4);
00234 SHA256Transform(ctx, ctx->block, block_nb);
00235 for (int i = 0 ; i < 8; i++)
00236 UNPACK32(ctx->h[i], &digest[i << 2]);
00237 }
00238
00239 void SHA256(const char *src, char *dest, int len, const char* hxc, const unsigned int* ikey = NULL)
00240 {
00241
00242 unsigned char bytehash[SHA256_DIGEST_SIZE];
00243 SHA256Context ctx;
00244 SHA256Init(&ctx, ikey);
00245 SHA256Update(&ctx, (unsigned char *)src, (unsigned int)len);
00246 SHA256Final(&ctx, bytehash);
00247
00248 for (int i = 0, j = 0; i < SHA256_DIGEST_SIZE; i++)
00249 {
00250 dest[j++] = hxc[bytehash[i] / 16];
00251 dest[j++] = hxc[bytehash[i] % 16];
00252 dest[j] = '\0';
00253 }
00254 }
00255
00256 unsigned int* key;
00257 char* chars;
00258
00259 public:
00260
00261 ModuleSHA256(InspIRCd* Me) : Module(Me), key(NULL), chars(NULL)
00262 {
00263 ServerInstance->Modules->PublishInterface("HashRequest", this);
00264 Implementation eventlist[] = { I_OnRequest };
00265 ServerInstance->Modules->Attach(eventlist, this, 1);
00266 }
00267
00268 virtual ~ModuleSHA256()
00269 {
00270 ServerInstance->Modules->UnpublishInterface("HashRequest", this);
00271 }
00272
00273
00274 virtual const char* OnRequest(Request* request)
00275 {
00276 HashRequest* SHA = (HashRequest*)request;
00277 if (strcmp("KEY", request->GetId()) == 0)
00278 {
00279 this->key = (unsigned int*)SHA->GetKeyData();
00280 }
00281 else if (strcmp("HEX", request->GetId()) == 0)
00282 {
00283 this->chars = (char*)SHA->GetOutputs();
00284 }
00285 else if (strcmp("SUM", request->GetId()) == 0)
00286 {
00287 static char data[MAXBUF];
00288 SHA256((const char*)SHA->GetHashData().data(), data, SHA->GetHashData().length(), chars ? chars : "0123456789abcdef", key);
00289 return data;
00290 }
00291 else if (strcmp("NAME", request->GetId()) == 0)
00292 {
00293 return "sha256";
00294 }
00295 else if (strcmp("RESET", request->GetId()) == 0)
00296 {
00297 this->chars = NULL;
00298 this->key = NULL;
00299 }
00300 return NULL;
00301 }
00302
00303 virtual Version GetVersion()
00304 {
00305 return Version("$Id: m_sha256.cpp 10291 2008-08-25 20:35:51Z w00t $", VF_VENDOR|VF_SERVICEPROVIDER, API_VERSION);
00306 }
00307 };
00308
00309 MODULE_INIT(ModuleSHA256)