HMAC SHA1调试, 在虚拟机和openwrt下运行结果不同?

2810阅读 0评论2013-07-29 qiushui_007
分类:LINUX

源码如下: 共2个. 

点击(此处)折叠或打开

  1. /******************************************************************************
  2.  *
  3.  * Copyright (C) 2012 kelo.yang
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation under the terms of the GNU General Public License is hereby
  7.  * granted. No representations are made about the suitability of this software
  8.  * for any purpose. It is provided "as is" without express or implied warranty.
  9.  * See the GNU General Public License for more details.
  10.  *
  11.  */
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>

  15. #if defined(__WIN32__) || defined(_WIN32)
  16.     typedef unsigned long    __u32;
  17.     typedef unsigned char    __u8;

  18. #else
  19.     typedef unsigned int    __u32;
  20.     typedef unsigned char    __u8;
  21. #endif

  22. typedef struct {
  23.     __u32 state[5];
  24.     __u32 count[2];
  25.     __u8 buffer[64];
  26. } SHA1_CTX;

  27. #if defined(rol)
  28. #undef rol
  29. #endif

  30. #define SHA1HANDSOFF

  31. #ifndef SHA_DIGESTSIZE
  32. #define SHA_DIGESTSIZE 20
  33. #endif

  34. #ifndef SHA_BLOCKSIZE
  35. #define SHA_BLOCKSIZE 64
  36. #endif

  37. #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))

  38. /* blk0() and blk() perform the initial expand. */
  39. /* I got the idea of expanding during the round function from SSLeay */
  40. #ifndef ___LITTLE_ENDIAN
  41. #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
  42.     |(rol(block->l[i],8)&0x00FF00FF))
  43. #else
  44. #define blk0(i) block->l[i]
  45. #endif
  46. #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
  47.     ^block->l[(i+2)&15]^block->l[i&15],1))

  48. /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
  49. #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
  50. #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
  51. #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
  52. #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
  53. #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);


  54. #define DBG printf

  55. //-----------------------------------------------------------------------------------------------

  56. /* Hash a single 512-bit block. This is the core of the algorithm. */
  57. void SHA1Transform(__u32 state[5], __u8 buffer[64])
  58. {
  59.     __u32 a, b, c, d, e;
  60.     typedef union {
  61.         unsigned char c[64];
  62.         __u32 l[16];
  63.     } CHAR64LONG16;

  64.     CHAR64LONG16* block;

  65. #ifdef SHA1HANDSOFF
  66.     static unsigned char workspace[64];
  67.     block = (CHAR64LONG16*)workspace;
  68.     //NdisMoveMemory(block, buffer, 64);
  69.     memcpy(block, buffer, 64);

  70. #else
  71.     block = (CHAR64LONG16*)buffer;
  72. #endif
  73.     /* Copy context->state[] to working vars */
  74.     a = state[0];
  75.     b = state[1];
  76.     c = state[2];
  77.     d = state[3];
  78.     e = state[4];
  79.     /* 4 rounds of 20 operations each. Loop unrolled. */
  80.     R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
  81.     R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
  82.     R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
  83.     R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
  84.     R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
  85.     R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
  86.     R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
  87.     R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
  88.     R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
  89.     R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
  90.     R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
  91.     R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
  92.     R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
  93.     R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
  94.     R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
  95.     R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
  96.     R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
  97.     R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
  98.     R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
  99.     R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
  100.     /* Add the working vars back into context.state[] */
  101.     state[0] += a;
  102.     state[1] += b;
  103.     state[2] += c;
  104.     state[3] += d;
  105.     state[4] += e;
  106.     /* Wipe variables */
  107.     a = b = c = d = e = 0;
  108. }

  109. /* SHA1Init - Initialize new context */
  110. void SHA1Init(SHA1_CTX* context)
  111. {
  112.     /* SHA1 initialization constants */
  113.     context->state[0] = 0x67452301;
  114.     context->state[1] = 0xEFCDAB89;
  115.     context->state[2] = 0x98BADCFE;
  116.     context->state[3] = 0x10325476;
  117.     context->state[4] = 0xC3D2E1F0;
  118.     context->count[0] = context->count[1] = 0;
  119. }

  120. /* Run your data through this. */
  121. void SHA1Update(SHA1_CTX* context, unsigned char* data, __u32 len)
  122. {
  123.     __u32 i, j;

  124.   j = context->count[0];
  125.   if ((context->count[0] += len << 3) < j)
  126.         context->count[1]++;
  127.   context->count[1] += (len>>29);
  128.   j = (j >> 3) & 63;
  129.   if ((j + len) > 63) {
  130.         //NdisMoveMemory(&context->buffer[j], data, (i = 64-j));
  131.     memcpy(&context->buffer[j], data, (i = 64-j));
  132.     SHA1Transform(context->state, context->buffer);
  133.     for ( ; i + 63 < len; i += 64) {
  134.         SHA1Transform(context->state, &data[i]);
  135.     }
  136.     j = 0;
  137.   }
  138.   else i = 0;
  139.   //NdisMoveMemory(&context->buffer[j], &data[i], len - i);
  140.   memcpy(&context->buffer[j], &data[i], len - i);
  141. }

  142. /* Add padding and return the message digest. */
  143. void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
  144. {
  145.     __u32 i, j;
  146.     unsigned char finalcount[8];

  147.   for (i = 0; i < 8; i++) {
  148.       finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
  149.        >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
  150.   }
  151.   SHA1Update(context, (unsigned char *)"\200", 1);
  152.   while ((context->count[0] & 504) != 448) {
  153.       SHA1Update(context, (unsigned char *)"\0", 1);
  154.   }
  155.   SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
  156.   for (i = 0; i < 20; i++) {
  157.       digest[i] = (unsigned char)
  158.        ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
  159.   }
  160.   i = j = 0;
  161.   memset(context->buffer, 0x00, 64);
  162.   memset(context->state, 0x00, 20);
  163.   memset(context->count, 0x00, 8);
  164.   memset(&finalcount, 0x00, 8);

  165. #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
  166.     SHA1Transform(context->state, context->buffer);
  167. #endif
  168. }

  169. void truncate(char* d1, char* d2, int len)
  170. {
  171.     int i ;
  172.     for (i = 0 ; i < len ; i++) d2[i] = d1[i];
  173. }

  174. /* Function to compute the digest */
  175. void hmac_sha(const char *k, const char *d, char *out)
  176. {
  177.     int    lk = strlen(k);
  178.     int    ld = strlen(d);

  179.     SHA1_CTX ictx, octx ;
  180.     char isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE] ;
  181.     char key[SHA_DIGESTSIZE] ;
  182.     char buf[SHA_BLOCKSIZE] ;
  183.     int i , j;
  184.     char str[100];

  185.     DBG("lk = %d, ld = %d\n", lk, ld);
  186.     if (lk > SHA_BLOCKSIZE) {
  187.         SHA1_CTX tctx ;
  188.         SHA1Init(&tctx) ;
  189.         SHA1Update(&tctx, (unsigned char* )k, lk) ;
  190.         SHA1Final((unsigned char *)key, &tctx) ;

  191.         k = key ;
  192.         lk = SHA_DIGESTSIZE ;
  193.     }

  194.     /**** Inner Digest ****/
  195.     SHA1Init(&ictx) ;

  196.     /* Pad the key for inner digest */
  197.     for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x36 ;
  198.     for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x36 ;

  199.     //SHA1Update(&ictx, buf, SHA_BLOCKSIZE) ;
  200.     SHA1Update(&ictx, (unsigned char *)buf, SHA_BLOCKSIZE) ;
  201.     SHA1Update(&ictx, (unsigned char *)d, ld) ;
  202.     SHA1Final((unsigned char *)isha, &ictx) ;

  203.     j = 0;
  204.     for (i=0; i<SHA_DIGESTSIZE; i++) {
  205.         j += sprintf(str+j, "%02X", (unsigned char)isha[i]);
  206.     }
  207.     DBG("hmac_sha: isha = %s\n", str);

  208.     /**** Outter Digest ****/
  209.     SHA1Init(&octx) ;

  210.     /* Pad the key for outter digest */
  211.     for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x5C ;
  212.     for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x5C ;

  213.     //SHA1Update(&octx, buf, SHA_BLOCKSIZE) ;
  214.     //SHA1Update(&octx, isha, SHA_DIGESTSIZE) ;
  215.     //SHA1Final(osha, &octx) ;
  216.     SHA1Update(&octx, (unsigned char *)buf, SHA_BLOCKSIZE) ;
  217.     SHA1Update(&octx, (unsigned char *)isha, SHA_DIGESTSIZE) ;
  218.     SHA1Final((unsigned char *)osha, &octx) ;

  219.     j = 0;
  220.     for (i=0; i<SHA_DIGESTSIZE; i++) {
  221.         j += sprintf(str+j, "%02X", (unsigned char)osha[i]);
  222.     }
  223.     DBG("hmac_sha: osha = %s\n", str);

  224.   truncate(osha, out, SHA_DIGESTSIZE);
  225.     j = 0;
  226.     for (i=0; i<SHA_DIGESTSIZE; i++) {
  227.         j += sprintf(str+j, "%02X", (unsigned char)out[i]);
  228.     }
  229.     DBG("hmac_sha: ret = %s\n", str);
  230. }

#调用代码如下, 

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #include "hmacSha1.h"

  5. #define HMAC_SHA1_OUT_LEN 21

  6. int main(int agrc, char *argv[])
  7. {
  8.     int i, j, len;
  9.     char str_tmp[100];

  10.     //---- hmac_sha1,
  11.     char *access_key = "E1y1RIxovXBM3riJ28fhhUU6auL7Ok";
  12.     //char access_key_len = strlen(access_key);
  13.     char *string_to_sign = "1234567890";
  14.     //char string_to_sign_len = strlen(string_to_sign);
  15.     char *hmac_sha1_out = (char *)malloc(sizeof(char) * HMAC_SHA1_OUT_LEN);

  16.     memset(hmac_sha1_out, 0, sizeof(hmac_sha1_out));
  17.     memset(str_tmp, 0, sizeof(str_tmp));
  18.     hmac_sha(access_key, string_to_sign, hmac_sha1_out);
  19.     j = 0;
  20.     len = strlen(hmac_sha1_out);
  21.     for (i=0; i<len; i++) {
  22.         j += sprintf(str_tmp +j, "%02X", (unsigned char)hmac_sha1_out[i]);
  23.     }
  24.     printf("hmac_sha : len = %d, %s\n", strlen(hmac_sha1_out), str_tmp);    //len = 20, BB86B7E01129ABB02826D69BC285B39771762759

  25.     free(hmac_sha1_out);
  26.     //---- hmac_sha1 End

  27.     return 1;
  28. }

#Makefile: 

点击(此处)折叠或打开

  1. OPENWRT = 0

  2. ifeq ($(OPENWRT), 1)
  3.     CC = ~/OpenWrt-SDK-ar71xx-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc

  4. else
  5.     CC = gcc
  6. endif

  7. CFLAGS += -Wall -O2
  8. #CFLAGS += -g

  9. #可执行文件名和相关的obj文件
  10. APP_BINARY = hello
  11. OBJ = hmac_sha1.o hmacSha1.o

  12. all: APP_FILE

  13. %.o: %.c
  14.     $(CC) $(CFLAGS) -c -o $@ $<

  15. #单独编译的文件部分放在此
  16. APP_FILE: $(OBJ)
  17.     $(CC) $(CFLAGS) $(OBJ) -o $(APP_BINARY)    $(LFLAGS)

  18. clean:
  19.     @echo "cleanning project"
  20.     $(RM) *.a *.o *~ *.so *.lo $(APP_BINARY)
  21.     @echo "clean completed"

  22. .PHONY: clean


1. 虚拟机, 运行结果如下
xxg@xxg-desktop:~/1-wire/hmac_sha1$ ./hello
lk = 30, ld = 10
hmac_sha: isha = 1C09351EBE14071F3EBD455E687C0182C69BD4BE
hmac_sha: osha = BB86B7E01129ABB02826D69BC285B39771762759
hmac_sha: ret = BB86B7E01129ABB02826D69BC285B39771762759
hmac_sha : len = 20, BB86B7E01129ABB02826D69BC285B39771762759

2. openwrt下, 运行结果如下
root@OpenWrt:/xutest# chmod +x hello
root@OpenWrt:/xutest# ./hello
lk = 30, ld = 10
hmac_sha: isha = 0BB90C8EA6E0E18D1EBD8EAFF173BABAA4596860
hmac_sha: osha = DAE4FD3CC9B58CBE23BABCCE5B62C14880FECEEB
hmac_sha: ret = DAE4FD3CC9B58CBE23BABCCE5B62C14880FECEEB
hmac_sha : len = 20, DAE4FD3CC9B58CBE23BABCCE5B62C14880FECEEB


解决: Makefile修改如下

点击(此处)折叠或打开

  1. OPENWRT = 0

  2. ifeq ($(OPENWRT), 1)
  3.   CC = ~/OpenWrt-SDK-ar71xx-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-gcc
  4.   DEFS = -D___LITTLE_ENDIAN
  5. else
  6.   CC = gcc
  7. endif

  8. CFLAGS += -Wall -O2 $(DEFS)
  9. #CFLAGS += -g

    


上一篇:阿里云OSS C SDK应用集锦
下一篇:大小端测试, 原来openwrt是大端存储模式(WR703N下测试)