请选择 进入手机版 | 继续访问电脑版

C语言实现hmac-sha1

本帖最后由 Darkbright.Liu 于 2019-11-15 19:43 编辑

// sha1.c:
  1. #include "sha1.h"

  2. #include <stddef.h>
  3. #include <string.h>

  4. #define SWAP(n) \
  5.     (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))

  6. #define BLOCKSIZE 4096

  7. static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };

  8. void sha1_init_ctx (struct sha1_ctx *ctx)
  9. {
  10.   ctx->A = 0x67452301;
  11.   ctx->B = 0xefcdab89;
  12.   ctx->C = 0x98badcfe;
  13.   ctx->D = 0x10325476;
  14.   ctx->E = 0xc3d2e1f0;

  15.   ctx->total[0] = ctx->total[1] = 0;
  16.   ctx->buflen = 0;
  17. }

  18. static __inline__ void set_uint32 (char *cp, uint32_t v)
  19. {
  20.   memcpy (cp, &v, sizeof v);
  21. }

  22. void * sha1_read_ctx(const struct sha1_ctx *ctx, void *resbuf)
  23. {
  24.   char *r = (char*)resbuf;
  25.   set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A));
  26.   set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B));
  27.   set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C));
  28.   set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D));
  29.   set_uint32 (r + 4 * sizeof ctx->E, SWAP (ctx->E));

  30.   return resbuf;
  31. }

  32. void * sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
  33. {
  34.   uint32_t bytes = ctx->buflen;
  35.   size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;

  36.   ctx->total[0] += bytes;
  37.   if (ctx->total[0] < bytes)
  38.     ++ctx->total[1];

  39.   ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
  40.   ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3);

  41.   memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);

  42.   sha1_process_block (ctx->buffer, size * 4, ctx);

  43.   return sha1_read_ctx (ctx, resbuf);
  44. }

  45. void * sha1_buffer (const char *buffer, size_t len, void *resblock)
  46. {
  47.   struct sha1_ctx ctx;

  48.   sha1_init_ctx (&ctx);

  49.   sha1_process_bytes (buffer, len, &ctx);

  50.   return sha1_finish_ctx (&ctx, resblock);
  51. }

  52. void sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
  53. {
  54.   if (ctx->buflen != 0)
  55.     {
  56.       size_t left_over = ctx->buflen;
  57.       size_t add = 128 - left_over > len ? len : 128 - left_over;

  58.       memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
  59.       ctx->buflen += add;

  60.       if (ctx->buflen > 64)
  61.         {
  62.           sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx);

  63.           ctx->buflen &= 63;
  64.           memcpy (ctx->buffer,
  65.                   &((char *) ctx->buffer)[(left_over + add) & ~63],
  66.                   ctx->buflen);
  67.         }

  68.       buffer = (const char *) buffer + add;
  69.       len -= add;
  70.     }

  71.   if (len >= 64)
  72.     {
  73.         while (len > 64)
  74.           {
  75.             sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
  76.             buffer = (const char *) buffer + 64;
  77.             len -= 64;
  78.           }
  79.       else
  80. #endif
  81.         {
  82.           sha1_process_block (buffer, len & ~63, ctx);
  83.           buffer = (const char *) buffer + (len & ~63);
  84.           len &= 63;
  85.         }
  86.     }

  87.   if (len > 0)
  88.     {
  89.       size_t left_over = ctx->buflen;

  90.       memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
  91.       left_over += len;
  92.       if (left_over >= 64)
  93.         {
  94.           sha1_process_block (ctx->buffer, 64, ctx);
  95.           left_over -= 64;
  96.           memcpy (ctx->buffer, &ctx->buffer[16], left_over);
  97.         }
  98.       ctx->buflen = left_over;
  99.     }
  100. }

  101. #define K1 0x5a827999
  102. #define K2 0x6ed9eba1
  103. #define K3 0x8f1bbcdc
  104. #define K4 0xca62c1d6

  105. #define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
  106. #define F2(B,C,D) (B ^ C ^ D)
  107. #define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
  108. #define F4(B,C,D) (B ^ C ^ D)

  109. void sha1_process_block(const void *buffer, size_t len, struct sha1_ctx *ctx)
  110. {
  111.   const uint32_t *words = (const uint32_t*)buffer;
  112.   size_t nwords = len / sizeof (uint32_t);
  113.   const uint32_t *endp = words + nwords;
  114.   uint32_t x[16];
  115.   uint32_t a = ctx->A;
  116.   uint32_t b = ctx->B;
  117.   uint32_t c = ctx->C;
  118.   uint32_t d = ctx->D;
  119.   uint32_t e = ctx->E;

  120.   ctx->total[0] += len;
  121.   if (ctx->total[0] < len)
  122.     ++ctx->total[1];
复制代码
// sha1.h:
  1. #ifndef SHA1_H
  2. #define SHA1_H

  3. #include <stdio.h>
  4. #include <stdint.h>

  5. #define SHA1_DIGEST_SIZE 20

  6. struct sha1_ctx
  7. {
  8.   uint32_t A;
  9.   uint32_t B;
  10.   uint32_t C;
  11.   uint32_t D;
  12.   uint32_t E;

  13.   uint32_t total[2];
  14.   uint32_t buflen;
  15.   uint32_t buffer[32];
  16. };

  17. void sha1_init_ctx(struct sha1_ctx *ctx);
  18. void sha1_process_block(const void *buffer, size_t len, struct sha1_ctx *ctx);
  19. void sha1_process_bytes(const void *buffer, size_t len, struct sha1_ctx *ctx);
  20. void *sha1_finish_ctx(struct sha1_ctx *ctx, void *resbuf);
  21. void *sha1_read_ctx(const struct sha1_ctx *ctx, void *resbuf);
  22. void *sha1_buffer(const char *buffer, size_t len, void *resblock);

  23. #endif
复制代码
// memxor.c:
  1. #include "memxor.h"

  2. void * memxor(void * dest, const void * src, size_t n)
  3. {
  4.   char const *s = (char const*)src;
  5.   char *d = (char*)dest;
  6.   for (; n > 0; n--)
  7.     *d++ ^= *s++;
  8.   return dest;
  9. }
复制代码
// memxor.h:
  1. #ifndef MEMXOR_H
  2. #define MEMXOR_H

  3. #include <stddef.h>

  4. void *memxor(void *  dest, const void *  src, size_t n);

  5. #endif
复制代码
// hmac-sha1.c:
  1. #include "hmac.h"

  2. #include "memxor.h"
  3. #include "sha1.h"

  4. #include <string.h>

  5. #define IPAD 0x36
  6. #define OPAD 0x5c

  7. int hmac_sha1(const void *key, size_t keylen, const void *in, size_t inlen, void *resbuf)
  8. {
  9.   struct sha1_ctx inner;
  10.   struct sha1_ctx outer;
  11.   char optkeybuf[20];
  12.   char block[64];
  13.   char innerhash[20];

  14.   if (keylen > 64)
  15.     {
  16.       struct sha1_ctx keyhash;

  17.       sha1_init_ctx (&keyhash);
  18.       sha1_process_bytes (key, keylen, &keyhash);
  19.       sha1_finish_ctx (&keyhash, optkeybuf);

  20.       key = optkeybuf;
  21.       keylen = 20;
  22.     }
  23.   sha1_init_ctx (&inner);

  24.   memset(block, IPAD, sizeof (block));
  25.   memxor(block, key, keylen);

  26.   sha1_process_block (block, 64, &inner);
  27.   sha1_process_bytes (in, inlen, &inner);

  28.   sha1_finish_ctx (&inner, innerhash);

  29.   sha1_init_ctx (&outer);

  30.   memset (block, OPAD, sizeof (block));
  31.   memxor (block, key, keylen);

  32.   sha1_process_block (block, 64, &outer);
  33.   sha1_process_bytes (innerhash, 20, &outer);

  34.   sha1_finish_ctx (&outer, resbuf);

  35.   return 0;
  36. }
复制代码
// hmac.h:
  1. #ifndef HMAC_H
  2. #define HMAC_H

  3. #include <stddef.h>

  4. int hmac_sha1(const void *key, size_t keylen, const void *in, size_t inlen, void *resbuf);

  5. #endif
复制代码


标签: 暂无标签
Darkbright.Liu

写了 7 篇文章,拥有财富 129,被 2 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

成为第一个吐槽的人

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

意见
反馈