加密算法中的数据类型问题 [英] Data type problem in encryption algorithm

查看:121
本文介绍了加密算法中的数据类型问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我非常需要你的帮助......我正在研究一个IPSec

的实现,几乎完成了,我发现了一个相当可观的问题。我正在发送一个特定的数组+一个HMAC-SHA1函数的密钥。

我用以下内容进行了测试:


void icv_Calculation_test(char p_output [20]){

char msgtest [] ="你什么都不想要?" ;;

char key [] =" Jefe";

uint8_t outputsha [20];

int size_message,size_key;

size_message = strlen(msgtest);

size_key = strlen(key);

hmac_sha(key,size_key,msgtest,size_message,outputsha,

sizeof(outputsha));

strcpy( p_output,outputsha);

返回;

}


我得到了预期的结果,如测试用例#2 RFC 2202:

0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79

然而,在我尝试匹配不同的

HMAC计算(来自发件人)之前,我认为一切正常和接收器)..他们没有匹配,我

然后意识到我每次都在生成不同的HMAC计算时间我

调用函数(来自发件人)。我尝试了其他测试用例来自

RFC 2202,然后我意识到我遇到了以下问题:


例如,当试图获得HMAC时测试用例的结果#1

其中包含:


char msgtest [] =" Hi There";

和键是0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B

我不知道如何处理它..我尝试了以下内容:


strtoul()..像这样:


char szInput [] =" 0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B" ;;

char * pEnd;

unsigned long ul;

ul = strtoul(szInput,& pEnd,0);


但是RFC 2202的HMAC功能需要键作为字符串..我很小

有点困惑,因为我不知道该怎么办。


底线,我在发送时没有得到预期的HMAC计算

以下函数,但在使用测试用例#2时,全部为

ascii,它工作正常..


下面是代码..它有点长,但我非常需要你的

帮助到这里..告诉我,如果你需要别的东西,为了更清楚..


这里我试图显示数据类型..

..........

typedef struct {

char * message;

char dest_ip [ 20];

char src_ip [20];

int msg_length;

int port;

char * key ;

char算法;

} CONF_PARAMS;

.............

uint8_t payload [sizeof(packet)+ sizeof(authenHeader_ext)];

uint8_t输出[output_size]

............. ..

icv_Calculation(payload,sizeof(payload),cnf,output,output_size);

..............

void icv_Calculation(char * hdrs,int hdrs_len,CONF_PARAMS * cnf,uint8_t

* output,int output_len){


if(b) cnf-> algorithm =='s'')

hmac_ sha(cnf-> key,strlen(cnf-> key),hdrs,hdrs_len,output,

sizeof(output));


}


hdrs是我的十六进制值,HMAC

计算的工作信息。


继承HMAC功能,.h和.c


#ifndef HMACSHA1_H_

#define HMACSHA1_H_


#include " sha1.h"

#ifndef SHA_DIGESTSIZE

#define SHA_DIGESTSIZE 20

#endif


#ifndef SHA_BLOCKSIZE

#define SHA_BLOCKSIZE 64

#endif


void pr_sha(FILE *,unsigned char *,int) ;

void truncate_sha1(char *,char *,int);

void hmac_sha(char *,int,char *,int,char *,int);


#endif / * HMACSHA1_H _ * /

------------------------- ---------

#include< stdio.h>

#include" sha1.h"

#包括hmac-sha1.h

/ *

*来自sha1.h - -----------------------

*

* sha1_context;

* void sha1_starts(sha1_context * ctx);

* void sha1_update(sha1_context * ctx,uint8 * input,uint32 length);

* void sha1_finish(sha1_context * ctx, uint8 digest [20]);

*

* /


/ *打印摘要的功能* /

void pr_sha(FILE * fp,unsigned char * s,int t){

int i;

fprintf(fp," 0x");

for(i = 0;我< t; i ++)

fprintf(fp,"%02x",s [i]);

fprintf(fp," 0");

}


void truncate_sha1(

char * d1,/ *数据被截断* /

char * d2, / *截断数据* /

int len / *以字节为单位的长度* /

){

int i;

for(i = 0; i< len; i ++)

d2 [i] = d1 [i];

}


/ *计算摘要的函数* /

void hmac_sha(

char * k,/ *密钥* /

int lk,/ *密钥长度,以字节为单位* /

char * d,/ * data * /

int ld,/ *数据长度,以字节为单位* /

char * out,/ *输出缓冲区,至少t字节* /

int t

){

sha1_context ictx,octx;

char isha [SHA_DIGESTSIZE],osha [SHA_DIGESTSIZE];

char key [SHA_DIGESTSIZE];

char buf [SHA_BLOCKSIZE];

int i;

if(lk& GT; SHA_BLOCKSIZE){


sha1_context tctx;


sha1_starts(& tctx);

sha1_update(& tctx ,k,lk);

sha1_finish(& tctx,key);


k = key;

lk = SHA_DIGESTSIZE;

}


/ ****内心摘要**** /


sha1_starts(& ictx );


/ *填充内部摘要的关键字* /

for(i = 0; i< lk; ++ i)
buf [i] = k [i] ^ 0x36;

for(i = lk; i< SHA_BLOCKSIZE; ++ i)buf [i] = 0x36;


sha1_update(& ictx,buf,SHA_BLOCKSIZE);

sha1_update(& ictx,d,ld);


sha1_finish(& ictx,isha);


/ **** Outter Digest **** /


sha1_starts(& octx);


/ *填写外部摘要的关键字* /


for(i = 0; i< lk; ++ i)

buf [i] = k [i] ^ 0x5C;

for(i = lk; i< SHA_BLOCKSIZE; ++ i)

buf [i] = 0x5C;


sha1_update(& octx,buf,SHA_BLOCKSIZE);

sha1_update(& octx,isha,SHA_DIGESTSIZE);


sha1_finish(& octx,osha) ;


/ *截断并打印结果* /

t = t> SHA_DIGESTSIZE? SHA_DIGESTSIZE:t;

truncate_sha1(osha,out,t);

pr_sha(stdout,out,t);


}


------------------------


和这是SHA1函数,对不起,如果这是一个很长的代码,但是我猜的是

问题是函数调用的起源..


/ *

*符合FIPS-180-1标准的SHA-1实施

*

*版权所有(C)2001-2003 Christophe Devine

*

*此程序是免费软件;您可以根据GNO通用公共许可证的条款重新分发和/或修改

*它由

*自由软件基金会发布;许可证的第2版,或者

*(根据您的选择)以后的任何版本。

*

*此程序在希望它有用,

*但没有任何保证;甚至没有暗示的保证

*适销性或特定用途的适用性。有关更多详细信息,请参阅

* GNU通用公共许可证。

*

*您应该已收到GNU通用公共许可证的副本

*以及该计划;如果没有,请写信给自由软件

* Foundation,Inc.,59 Temple Place,Suite 330,Boston,MA

02111-1307 USA

* /


#include< string.h>


#include" sha1.h"


#define GET_UINT32(n,b,i)\

{\

(n)=((uint32)(b)[( i)]<< 24)\

| ((uint32)(b)[(i)+ 1]<< 16)\

| ((uint32)(b)[(i)+ 2]<< 8)\

| ((uint32)(b)[(i)+ 3]); \

}


#define PUT_UINT32(n,b,i)\

{\

(b)[(i)] =(uint8)((n)>> 24); \\ b
(b)[(i)+ 1] =(uint8)((n)>> 16); \\ b
(b)[(i)+ 2] =(uint8)((n)>> 8); \\ b
(b)[(i)+ 3] =(uint8)((n)); \

}


void sha1_starts(sha1_context * ctx)

{

ctx-> ; total [0] = 0;

ctx-> total [1] = 0;


ctx-> state [0] = 0x67452301;

ctx-> state [1] = 0xEFCDAB89;

ctx-> state [2] = 0x98BADCFE;

ctx-> state [3] = 0x10325476;

ctx-> state [4] = 0xC3D2E1F0;

}


void sha1_process( sha1_context * ctx,uint8 data [64])

{

uint32 temp,W [16],A,B,C,D,E;


GET_UINT32(W [0],数据,0);

GET_UINT32(W [1],数据,4);

GET_UINT32(W [2],数据,8);

GET_UINT32(W [3],数据,12);

GET_UINT32(W [4],数据,16);

GET_UINT32(W [5],数据,20);

GET_UINT32(W [6],数据,24);

GET_UINT32(W [7],数据,28);

GET_UINT32(W [8],数据,32);

GET_UINT32(W [9],数据,36);

GET_UINT32(W [10],数据,40);

GET _UINT32(W [11],数据,44);

GET_UINT32(W [12],数据,48);

GET_UINT32(W [13],数据,52 );

GET_UINT32(W [14],数据,56);

GET_UINT32(W [15],数据,60);


#define S(x,n)((x<< n)| ((x& 0xFFFFFFFF)>>(32 - n)))


#define R(t)\

(\

temp = W [(t - 3)& 0x0F] ^ W [(t - 8)& 0x0F] ^ \

W [(t - 14) & 0x0F] ^ W [t& 0x0F],\

(W [t& 0x0F] = S(temp,1))\




#define P(a,b,c,d,e,x)\

{\

e + = S(a,5)+ F(b,c,d)+ K + x; b = S(b,30); \

}


A = ctx->州[0];

B = ctx->州[ 1];

C = ctx->州[2];

D = ctx->州[3];

E = ctx-> state [4];


#define F(x,y,z)(z ^(x&(y ^ z)))

#define K 0x5A827999

P(A,B,C,D,E,W [0]);

P(E, A,B,C,D,W [1]);

P(D,E,A,B,C,W [2]);

P( C,D,E,A,B,W [3]);

P(B,C,D,E,A,W [4]);

P(A,B,C,D,E,W [5]);

P(E,A,B,C,D,W [6]);

P(D,E,A,B,C,W [7]);

P(C,D,E,A,B,W [8]);

P(B,C,D,E,A,W [9]);

P(A,B,C,D,E,W [10]);

P(E,A,B,C,D,W [11]);

P(D,E,A,B,C,W [12]);

P(C,D,E,A,B,W [13]);

P(B,C,D,E,A,W [14] );

P(A,B,C,D,E,W [15]);

P(E,A,B,C,D,R( 16));

P(D,E,A,B,C,R(17));

P(C,D,E,A, B,R(18));

P(B,C,D,E,A,R(19));


#undef K

#undef F


#define F(x,y,z)(x ^ y ^ z)

#define K 0x6ED9EBA1


P(A,B,C,D,E,R(20));

P(E,A,B,C,D ,R(21));

P(D,E,A,B,C,R(22));

P(C,D,E,A ,B,R(23));

P(B,C,D,E,A,R(24));

P(A,B,C ,D,E,R(25));

P(E,A,B,C,D,R(26));

P(D,E ,A,B,C,R(27));

P(C,D,E,A,B,R(28));

P(B ,C,D,E,A,R(29));

P(A,B,C,D,E,R(30));

P (E,A,B,C,D,R(31));

P(D,E,A,B,C,R(32));

P(C,D,E,A,B,R(33));

P(B,C,D,E,A,R(34));

P(A,B,C,D,E,R(35));

P(E,A,B,C,D,R(36));

P(D,E,A,B,C,R(37));

P(C,D,E,A,B,R(38));

P(B,C,D,E,A,R(39));


#undef K

#undef F


#define F(x,y,z)((x& y)| (z&(x | y)))

#define K 0x8F1BBCDC

P(A,B,C,D,E,R(40) ));

P(E,A,B,C,D,R(41));

P(D,E,A,B,C,R (42));

P(C,D,E,A,B,R(43));

P(B,C,D,E,A ,R(44));

P(A,B,C,D,E,R(45));

P(E,A,B,C ,D,R(46));

P(D,E,A,B,C,R(47));

P(C,D,E ,A,B,R(48));

P(B,C,D,E,A,R(49));

P(A,B ,C,D,E,R(50));

P(E,A,B,C,D,R(51));

P(D ,E,A,B,C,R(52));

P(C,D,E,A,B,R(53));

P (B,C,D,E,A,R(54));

P(A,B,C,D,E,R(55));

P(E,A,B,C,D,R(56));

P(D,E,A,B,C,R(57));

P(C,D,E,A,B,R(58));

P(B,C,D,E,A,R(59));


#undef K

#undef F


#define F(x,y,z)(x ^ y ^ z)

#define K 0xCA62C1D6

P(A,B,C,D,E,R(60));

P(E,A,B,C,D,R(61));

P(D,E,A,B,C,R(62));

P(C,D,E,A,B,R(63));

P(B,C,D,E,A,R(64));

P(A,B,C,D,E,R(65));

P(E,A,B,C,D,R(66));

P(D,E,A,B,C,R(67));

P(C,D,E,A,B,R(68));

P(B,C,D,E,A,R(69));

P(A,B,C,D,E,R(70) );

P(E,A,B,C,D,R(71));

P(D,E,A,B,C,R( 72));

P(C,D,E,A,B,R(73));

P(B,C,D,E,A, R(74));

P(A,B,C,D,E,R(75));

P(E,A,B,C, D,R(76));

P(D,E,A,B,C,R(77));

P(C,D,E, A,B,R(78));

P(B,C,D,E,A,R(79));


#undef K

#undef F


ctx-> state [0] + = A;

ctx-> state [ 1] + = B;

ctx->州[2] + = C;

ctx->州[3] + = D;

ctx-> state [4] + = E;

}


void sha1_update(sha1_context * ct x,uint8 *输入,uint32长度)

{

uint32 left,fill;


if(!长度)返回;


left = ctx-> total [0]& 0x3F;

fill = 64 - left;


ctx-> total [0] + = length;

ctx- > total [0]& = 0xFFFFFFFF;


if(ctx-> total [0]< length)

ctx-> total [1] ++;


if(left&& length> = fill)

{

memcpy( (void *)(ctx-> buffer + left),

(void *)input,fill);

sha1_process(ctx,ctx-> buffer);

长度 - =填充;

输入+ =填充;

left = 0;

}


while(长度> = 64)

{

sha1_process(ctx,输入);

长度 - = 64;

输入+ = 64;

}


如果(长度)

{

memcpy((void *)(ctx-> buffer + left),

(void *)输入,长度);

}

}


静态uint8 sha1_padding [64] =

{

0x80,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0

0,0,0,0,0,0,0, 0,0,0,0,0,0, 0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

0,0,0,0,0,0,0,0,0,0,0,0,0,0

};


void sha1_finish(sha1_context * ctx,uint8 digest [20])

{

uint32 last,padn;

uint32高,低;

uint8 msglen [8];


high =(ctx-> total [0]>> 29)

| (ctx->总计[1] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
PUT_UINT32(高,msglen,0);

PUT_UINT32(低,msglen,4);


last = ctx-> total [ 0]& 0x3F;

padn =(last< 56)? (56 - last):( 120 - last);


sha1_update(ctx,sha1_padding,padn);

sha1_update(ctx,msglen,8);


PUT_UINT32(ctx-> state [0],digest,0);

PUT_UINT32(ctx-> state [1],digest,4 );

PUT_UINT32(ctx-> state [2],digest,8);

PUT_UINT32(ctx-> state [3],digest,12);

PUT_UINT32(ctx-> state [4],digest,16);

}

FBM

解决方案

Fernando Barsoba写道:

大家好,

我非常需要你们的帮助...我是从事IPSec实施,几乎完成后,我发现了一个相当大的问题。我正在发送一个特定的数组+一个HMAC-SHA1函数的密钥。
我做了以下测试:

void icv_Calculation_test(char p_output [20]){
char msgtest [] ="你想做什么?" ;;
char key [] =" Jefe" ;;
uint8_t outputsha [20];
int size_message, size_key;
size_message = strlen(msgtest);
size_key = strlen(key);
hmac_sha(key,size_key,msgtest,size_message,outputsha,
sizeof(outputsha));
strcpy(p_output,outputsha);
返回;
}
我得到了预期的结果,如RFC 2202中的测试用例#2:
0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79
然而,我认为一切正常,直到我尝试匹配不同的HMAC计算(来自发送者和接收者)......他们并不匹配,我
然后意识到我每次调用函数(发件人)时都会生成不同的HMAC计算。我尝试了来自RFC 2202的其他测试用例,然后我意识到我遇到了以下问题:

例如,当试图获得测试用例#1的HMAC结果时其中包括:

char msgtest [] =" Hi There" ;;
,密钥是0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B

我不知道怎么处理用它..我尝试了以下内容:

strtoul()..像这样:




< snip>


忘了strtoul(),这太久了。您需要将此

十六进制字符串转换为实际的字节序列。看看你是否有一个库

函数来执行此操作。


如果没有,这是一个示例实现,我在几秒钟内掀起了

(所以不要相信它,不要指望它快速):


#include< stdlib.h>

#include< string.h>


/ *将单个十六进制数字''c''转换为相应的

整数,如果''c''不是十六进制数字,则为-1。 * /

int hexdigit_to_int(char c){

if(c> =''0''&& c< ='''9'')返回c - ''0'';

开关(c){

case''a'':case''A'':返回10;

case''b'':case''B'':返回11;

case''c'':case''C'':返回12;

case''d'':case''D'':返回13;

case''e'':case''E'':返回14;

case''f'':case''F'':返回15;

默认值:{

返回-1;

}

}

}


/ *将字节序列的十六进制表示转换为

字节序列。 * /

/ *如果

成功则返回malloc() - 分配的strlen(十六进制)/ 2字节块,否则返回空指针。 * /

unsigned char * hexstr_to_bytes(const char * hex){

size_t l = strlen(hex);

size_t n = 0;

unsigned char * result;

if(l%2!= 0)返回NULL;


result = malloc(l / 2);

if(!result)返回NULL;


while(n< l){

int d1 = hexdigit_to_int(hex [n])* 16;

int d2 = hexdigit_to_int(hex [n + 1]);

if(d1 == -1 || d2 == -1){

免费(结果);

返回NULL;

}

结果[n / 2] = d1 + d2;

n + = 2;

}

返回结果;

}


请记住,输入字符串不能以0x开头,你要求
必须释放()结果并且*不是*一个以null结尾的字符串但是

a一个长度的字节序列你必须跟踪自己,所以没有

在它上面调用strlen()。


S.


Skarmander写道: Fernando Barsoba写道:

大家好,

我非常需要你的帮助...我正在研究IPSec
void icv_Calculation_test(char p_output [20]){
char msgtest [] =你想要什么?;
char key [] =" Jefe";
uint8_t outputsha [20];
int size_message,size_key;
size_message = strlen(msgtest);
size_key = strlen(key );
hmac_sha(key,size_key,msgtest,size_message,outputsha,
sizeof(outputsha));
strcpy(p_output,outputsha);
return;
}

我得到了预期的结果,如RFC 2202中的测试用例#2:
0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79
然而,在我尝试匹配之前,我认为一切正常不同的HMAC计算(来自发送者和接收者)..他们没有匹配,然后我意识到我每次都会生成不同的HMAC计算
我调用了函数(来自发送者)。我从RFC 2202尝试了其他测试用例,然后我意识到我遇到了以下问题:

例如,当试图获得测试用例#1的HMAC结果时其中包括:

char msgtest [] =" Hi There" ;;
,密钥是0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B

我不知道如何处理用它..我尝试了以下内容:

strtoul()..像这样:



< snip>

忘了strtoul(),这太久了。您需要将此
十六进制字符串转换为实际的字节序列。看看你是否在某个地方有一个库
功能。

如果没有,这是一个示例实现我在几秒钟内掀起
(所以不要''相信它,不要指望它快速):

#include< stdlib.h>
#include< string.h>



非常感谢,我会试试这个......但是,我有什么问题背后的概念是什么?我的意思是,为什么当我尝试获取消息摘要

a特定的''字符串''消息和特定的''字符串''键时,函数

有效(消息摘要)总是一样的),当我尝试使用相同的字符串键,但是不同的''字符串''消息时,我不会尝试



这些消息之间的区别仅在于后者的十六进制

内容对我来说很重要..我的意思是,而不是:


char msgtest [] ="你什么都不想要什么?" ;;

char key [] =" Jefe";


我有一个char *,其十六进制内容对我来说很重要..


谢谢,


FBM


Fernando Barsoba写道:

Skarmander写道:

Fernando Barsoba写道:

大家好,

我非常需要你的帮助......我正在开发一个IPSec
实现,几乎完成后,我发现了相当多的问题。我正在发送一个特定的数组+一个HMAC-SHA1功能键。我用以下方法进行了测试:

void icv_Calculation_test(char p_output [20]){
char msgtest [] =你想要什么?;
char key [] =" Jefe";
uint8_t outputsha [20];
int size_message,size_key;
size_message = strlen(msgtest);
size_key = strlen(key );
hmac_sha(key,size_key,msgtest,size_message,outputsha,
sizeof(outputsha));
strcpy(p_output,outputsha);
return;
}

我得到了预期的结果,如RFC 2202中的测试用例#2:
0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79

< snip>例如,当试图获得测试用例#1的HMAC结果时,其中包含:

char msgtest [] =" Hi There" ;;
,密钥为0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B


< snip>我的意思是,为什么当我尝试获取特定字符串消息和特定字符串键的消息摘要时,该功能
有效(消息摘要始终相同),以及它不是当我尝试使用相同的字符串键,而是一个不同的''字符串''消息时?这些消息之间唯一的区别是,对于后者,hex内容对我来说很重要。我的意思是,而不是:

char msgtest [] = 你想要什么,什么都不需要?;
char key [] =" Jefe" ;;

我有一个char *,其十六进制内容对我来说很重要..




SHA函数(显然)需要一个字节序列的键。

正如它所发生的那样,Jefe是一个字节序列:假设你的系统

使用与ASCII兼容的字符集,序列可以用十六进制表示为
为0x4A65666500。

这就是为什么将字符串传递给函数just are:字符串是

已经是一个字节序列。在第二个例子中(key = 0x0b0b0b ...)

你要传递一个实际的字节序列,表示为一串

十六进制数字,而不是字符串0x0b0b0b ......,这是

完全不同的东西。


S.


Hi all,

I very much need your help here guys.. I''m working on a IPSec
implementation, and when almost finished, I found a considerable
problem. I''m sending a particular array + a key to a HMAC-SHA1 function.
I did the tests with the following:

void icv_Calculation_test(char p_output[20]) {
char msgtest[]="what do ya want for nothing?";
char key[]="Jefe";
uint8_t outputsha[20];
int size_message, size_key;
size_message = strlen(msgtest);
size_key = strlen(key);
hmac_sha(key, size_key, msgtest, size_message, outputsha,
sizeof(outputsha));
strcpy(p_output, outputsha);
return;
}

And I got the expected result, as in test case #2 from RFC 2202:
0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79

However, I thought everything was ok until I tried to match different
HMAC calculations (from sender and receiver).. they didn''t match and I
then realized I was generating different HMAC calculations every time I
called the function (from sender). I tried then other test cases from
RFC 2202, and then I realized I had problems with the following:

For instance, when trying to obtain the HMAC result for test case #1
which has:

char msgtest[]="Hi There";
and the key is 0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B

I''m not sure how to deal with it.. I tried the following:

strtoul().. like this:

char szInput[]="0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B";
char * pEnd;
unsigned long ul;
ul = strtoul (szInput,&pEnd,0);

But the HMAC functions from RFC 2202 need keys as strings.. I''m a little
bit confused because I don''t know what to do with it.

Bottom line, I''m not getting the expected HMAC calculation when sending
to the function the following, but when using test case #2, which is all
ascii, it works fine..

Below is the code.. It''s a little bit long, but I very much need your
help here.. Tell me if you need something else for this to be more clear..

Here i''m trying to show the data types..
..........
typedef struct {
char * message;
char dest_ip[20];
char src_ip[20];
int msg_length;
int port;
char * key;
char algorithm;
} CONF_PARAMS;
.............
uint8_t payload[sizeof(packet) + sizeof(authenHeader_ext)];
uint8_t output[output_size]
...............
icv_Calculation(payload, sizeof(payload), cnf, output, output_size);
..............
void icv_Calculation(char *hdrs, int hdrs_len, CONF_PARAMS *cnf, uint8_t
*output, int output_len) {

if (cnf->algorithm == ''s'' )
hmac_sha(cnf->key, strlen(cnf->key), hdrs, hdrs_len, output,
sizeof(output));

}

hdrs is where I have my hex values, the message over which the HMAC
calculation works.

Heres the HMAC function, .h and .c

#ifndef HMACSHA1_H_
#define HMACSHA1_H_

#include "sha1.h"
#ifndef SHA_DIGESTSIZE
#define SHA_DIGESTSIZE 20
#endif

#ifndef SHA_BLOCKSIZE
#define SHA_BLOCKSIZE 64
#endif

void pr_sha(FILE*, unsigned char*, int);
void truncate_sha1 (char*, char*, int);
void hmac_sha (char*, int, char*, int, char*, int);

#endif /*HMACSHA1_H_*/
----------------------------------
#include <stdio.h>
#include "sha1.h"
#include "hmac-sha1.h"
/*
* From sha1.h ------------------------
*
* sha1_context;
* void sha1_starts( sha1_context *ctx );
* void sha1_update( sha1_context *ctx, uint8 *input, uint32 length );
* void sha1_finish( sha1_context *ctx, uint8 digest[20] );
*
*/

/* Function to print the digest */
void pr_sha(FILE* fp, unsigned char* s, int t) {
int i;
fprintf(fp, "0x");
for (i = 0 ; i < t ; i++)
fprintf(fp, "%02x", s[i]);
fprintf(fp, "0");
}

void truncate_sha1 (
char* d1, /* data to be truncated */
char* d2, /* truncated data */
int len /* length in bytes to keep */
) {
int i;
for (i=0; i < len; i++)
d2[i] = d1[i];
}

/* Function to compute the digest */
void hmac_sha (
char* k, /* secret key */
int lk, /* length of the key in bytes */
char* d, /* data */
int ld, /* length of data in bytes */
char* out, /* output buffer, at least "t" bytes */
int t
) {
sha1_context ictx, octx;
char isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE];
char key[SHA_DIGESTSIZE];
char buf[SHA_BLOCKSIZE];
int i;
if (lk > SHA_BLOCKSIZE) {

sha1_context tctx;

sha1_starts(&tctx);
sha1_update(&tctx, k, lk);
sha1_finish(&tctx, key);

k = key;
lk = SHA_DIGESTSIZE;
}

/**** Inner Digest ****/

sha1_starts(&ictx);

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

sha1_update(&ictx, buf, SHA_BLOCKSIZE);
sha1_update(&ictx, d, ld);

sha1_finish(&ictx, isha);

/**** Outter Digest ****/

sha1_starts(&octx);

/* Pad the key for outter digest */

for (i = 0 ; i < lk ; ++i)
buf[i] = k[i] ^ 0x5C;
for (i = lk ; i < SHA_BLOCKSIZE ; ++i)
buf[i] = 0x5C;

sha1_update(&octx, buf, SHA_BLOCKSIZE);
sha1_update(&octx, isha, SHA_DIGESTSIZE);

sha1_finish(&octx, osha);

/* truncate and print the results */
t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t;
truncate_sha1(osha, out, t);
pr_sha(stdout, out, t);

}

------------------------

And here''s the SHA1 function, sorry if this is a long code, but the
problem I guess is in the origin of the function calls..

/*
* FIPS-180-1 compliant SHA-1 implementation
*
* Copyright (C) 2001-2003 Christophe Devine
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*/

#include <string.h>

#include "sha1.h"

#define GET_UINT32(n,b,i) \
{ \
(n) = ( (uint32) (b)[(i) ] << 24 ) \
| ( (uint32) (b)[(i) + 1] << 16 ) \
| ( (uint32) (b)[(i) + 2] << 8 ) \
| ( (uint32) (b)[(i) + 3] ); \
}

#define PUT_UINT32(n,b,i) \
{ \
(b)[(i) ] = (uint8) ( (n) >> 24 ); \
(b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
(b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
(b)[(i) + 3] = (uint8) ( (n) ); \
}

void sha1_starts( sha1_context *ctx )
{
ctx->total[0] = 0;
ctx->total[1] = 0;

ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
}

void sha1_process( sha1_context *ctx, uint8 data[64] )
{
uint32 temp, W[16], A, B, C, D, E;

GET_UINT32( W[0], data, 0 );
GET_UINT32( W[1], data, 4 );
GET_UINT32( W[2], data, 8 );
GET_UINT32( W[3], data, 12 );
GET_UINT32( W[4], data, 16 );
GET_UINT32( W[5], data, 20 );
GET_UINT32( W[6], data, 24 );
GET_UINT32( W[7], data, 28 );
GET_UINT32( W[8], data, 32 );
GET_UINT32( W[9], data, 36 );
GET_UINT32( W[10], data, 40 );
GET_UINT32( W[11], data, 44 );
GET_UINT32( W[12], data, 48 );
GET_UINT32( W[13], data, 52 );
GET_UINT32( W[14], data, 56 );
GET_UINT32( W[15], data, 60 );

#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))

#define R(t) \
( \
temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
( W[t & 0x0F] = S(temp,1) ) \
)

#define P(a,b,c,d,e,x) \
{ \
e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
}

A = ctx->state[0];
B = ctx->state[1];
C = ctx->state[2];
D = ctx->state[3];
E = ctx->state[4];

#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999

P( A, B, C, D, E, W[0] );
P( E, A, B, C, D, W[1] );
P( D, E, A, B, C, W[2] );
P( C, D, E, A, B, W[3] );
P( B, C, D, E, A, W[4] );
P( A, B, C, D, E, W[5] );
P( E, A, B, C, D, W[6] );
P( D, E, A, B, C, W[7] );
P( C, D, E, A, B, W[8] );
P( B, C, D, E, A, W[9] );
P( A, B, C, D, E, W[10] );
P( E, A, B, C, D, W[11] );
P( D, E, A, B, C, W[12] );
P( C, D, E, A, B, W[13] );
P( B, C, D, E, A, W[14] );
P( A, B, C, D, E, W[15] );
P( E, A, B, C, D, R(16) );
P( D, E, A, B, C, R(17) );
P( C, D, E, A, B, R(18) );
P( B, C, D, E, A, R(19) );

#undef K
#undef F

#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1

P( A, B, C, D, E, R(20) );
P( E, A, B, C, D, R(21) );
P( D, E, A, B, C, R(22) );
P( C, D, E, A, B, R(23) );
P( B, C, D, E, A, R(24) );
P( A, B, C, D, E, R(25) );
P( E, A, B, C, D, R(26) );
P( D, E, A, B, C, R(27) );
P( C, D, E, A, B, R(28) );
P( B, C, D, E, A, R(29) );
P( A, B, C, D, E, R(30) );
P( E, A, B, C, D, R(31) );
P( D, E, A, B, C, R(32) );
P( C, D, E, A, B, R(33) );
P( B, C, D, E, A, R(34) );
P( A, B, C, D, E, R(35) );
P( E, A, B, C, D, R(36) );
P( D, E, A, B, C, R(37) );
P( C, D, E, A, B, R(38) );
P( B, C, D, E, A, R(39) );

#undef K
#undef F

#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC

P( A, B, C, D, E, R(40) );
P( E, A, B, C, D, R(41) );
P( D, E, A, B, C, R(42) );
P( C, D, E, A, B, R(43) );
P( B, C, D, E, A, R(44) );
P( A, B, C, D, E, R(45) );
P( E, A, B, C, D, R(46) );
P( D, E, A, B, C, R(47) );
P( C, D, E, A, B, R(48) );
P( B, C, D, E, A, R(49) );
P( A, B, C, D, E, R(50) );
P( E, A, B, C, D, R(51) );
P( D, E, A, B, C, R(52) );
P( C, D, E, A, B, R(53) );
P( B, C, D, E, A, R(54) );
P( A, B, C, D, E, R(55) );
P( E, A, B, C, D, R(56) );
P( D, E, A, B, C, R(57) );
P( C, D, E, A, B, R(58) );
P( B, C, D, E, A, R(59) );

#undef K
#undef F

#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6

P( A, B, C, D, E, R(60) );
P( E, A, B, C, D, R(61) );
P( D, E, A, B, C, R(62) );
P( C, D, E, A, B, R(63) );
P( B, C, D, E, A, R(64) );
P( A, B, C, D, E, R(65) );
P( E, A, B, C, D, R(66) );
P( D, E, A, B, C, R(67) );
P( C, D, E, A, B, R(68) );
P( B, C, D, E, A, R(69) );
P( A, B, C, D, E, R(70) );
P( E, A, B, C, D, R(71) );
P( D, E, A, B, C, R(72) );
P( C, D, E, A, B, R(73) );
P( B, C, D, E, A, R(74) );
P( A, B, C, D, E, R(75) );
P( E, A, B, C, D, R(76) );
P( D, E, A, B, C, R(77) );
P( C, D, E, A, B, R(78) );
P( B, C, D, E, A, R(79) );

#undef K
#undef F

ctx->state[0] += A;
ctx->state[1] += B;
ctx->state[2] += C;
ctx->state[3] += D;
ctx->state[4] += E;
}

void sha1_update( sha1_context *ctx, uint8 *input, uint32 length )
{
uint32 left, fill;

if( ! length ) return;

left = ctx->total[0] & 0x3F;
fill = 64 - left;

ctx->total[0] += length;
ctx->total[0] &= 0xFFFFFFFF;

if( ctx->total[0] < length )
ctx->total[1]++;

if( left && length >= fill )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, fill );
sha1_process( ctx, ctx->buffer );
length -= fill;
input += fill;
left = 0;
}

while( length >= 64 )
{
sha1_process( ctx, input );
length -= 64;
input += 64;
}

if( length )
{
memcpy( (void *) (ctx->buffer + left),
(void *) input, length );
}
}

static uint8 sha1_padding[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

void sha1_finish( sha1_context *ctx, uint8 digest[20] )
{
uint32 last, padn;
uint32 high, low;
uint8 msglen[8];

high = ( ctx->total[0] >> 29 )
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );

PUT_UINT32( high, msglen, 0 );
PUT_UINT32( low, msglen, 4 );

last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );

sha1_update( ctx, sha1_padding, padn );
sha1_update( ctx, msglen, 8 );

PUT_UINT32( ctx->state[0], digest, 0 );
PUT_UINT32( ctx->state[1], digest, 4 );
PUT_UINT32( ctx->state[2], digest, 8 );
PUT_UINT32( ctx->state[3], digest, 12 );
PUT_UINT32( ctx->state[4], digest, 16 );
}
FBM

解决方案

Fernando Barsoba wrote:

Hi all,

I very much need your help here guys.. I''m working on a IPSec
implementation, and when almost finished, I found a considerable
problem. I''m sending a particular array + a key to a HMAC-SHA1 function.
I did the tests with the following:

void icv_Calculation_test(char p_output[20]) {
char msgtest[]="what do ya want for nothing?";
char key[]="Jefe";
uint8_t outputsha[20];
int size_message, size_key;
size_message = strlen(msgtest);
size_key = strlen(key);
hmac_sha(key, size_key, msgtest, size_message, outputsha,
sizeof(outputsha));
strcpy(p_output, outputsha);
return;
}

And I got the expected result, as in test case #2 from RFC 2202:
0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79

However, I thought everything was ok until I tried to match different
HMAC calculations (from sender and receiver).. they didn''t match and I
then realized I was generating different HMAC calculations every time I
called the function (from sender). I tried then other test cases from
RFC 2202, and then I realized I had problems with the following:

For instance, when trying to obtain the HMAC result for test case #1
which has:

char msgtest[]="Hi There";
and the key is 0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B

I''m not sure how to deal with it.. I tried the following:

strtoul().. like this:



<snip>

Forget strtoul(), this is too long for a long. You need to convert this
hexstring to an actual sequence of bytes. See if you have a library
function somewhere to do this.

If not, here''s an example implementation I whipped up in a few seconds
(so don''t trust it, and don''t count on it being fast):

#include <stdlib.h>
#include <string.h>

/* Convert the single hexadecimal digit ''c'' to the corresponding
integer, or -1 if ''c'' is not a hex digit. */
int hexdigit_to_int(char c) {
if (c >= ''0'' && c <= ''9'') return c - ''0'';
switch (c) {
case ''a'': case ''A'': return 10;
case ''b'': case ''B'': return 11;
case ''c'': case ''C'': return 12;
case ''d'': case ''D'': return 13;
case ''e'': case ''E'': return 14;
case ''f'': case ''F'': return 15;
default: {
return -1;
}
}
}

/* Convert the hexadecimal representation of a sequence of bytes to
the sequence of bytes. */
/* Returns a malloc()-allocated block of strlen(hex) / 2 bytes if
successful or a null pointer otherwise. */
unsigned char* hexstr_to_bytes(const char* hex) {
size_t l = strlen(hex);
size_t n = 0;
unsigned char* result;
if (l % 2 != 0) return NULL;

result = malloc(l / 2);
if (!result) return NULL;

while (n < l) {
int d1 = hexdigit_to_int(hex[n]) * 16;
int d2 = hexdigit_to_int(hex[n + 1]);
if (d1 == -1 || d2 == -1) {
free(result);
return NULL;
}
result[n / 2] = d1 + d2;
n += 2;
}
return result;
}

Keep in mind that the input string must not begin with "0x", that you
must free() the result and that it is *not* a null-terminated string but
a sequence of bytes of a length you must keep track of yourself, so no
calling strlen() on it.

S.


Skarmander wrote:

Fernando Barsoba wrote:

Hi all,

I very much need your help here guys.. I''m working on a IPSec
implementation, and when almost finished, I found a considerable
problem. I''m sending a particular array + a key to a HMAC-SHA1
function. I did the tests with the following:

void icv_Calculation_test(char p_output[20]) {
char msgtest[]="what do ya want for nothing?";
char key[]="Jefe";
uint8_t outputsha[20];
int size_message, size_key;
size_message = strlen(msgtest);
size_key = strlen(key);
hmac_sha(key, size_key, msgtest, size_message, outputsha,
sizeof(outputsha));
strcpy(p_output, outputsha);
return;
}

And I got the expected result, as in test case #2 from RFC 2202:
0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79

However, I thought everything was ok until I tried to match different
HMAC calculations (from sender and receiver).. they didn''t match and I
then realized I was generating different HMAC calculations every time
I called the function (from sender). I tried then other test cases
from RFC 2202, and then I realized I had problems with the following:

For instance, when trying to obtain the HMAC result for test case #1
which has:

char msgtest[]="Hi There";
and the key is 0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B

I''m not sure how to deal with it.. I tried the following:

strtoul().. like this:



<snip>

Forget strtoul(), this is too long for a long. You need to convert this
hexstring to an actual sequence of bytes. See if you have a library
function somewhere to do this.

If not, here''s an example implementation I whipped up in a few seconds
(so don''t trust it, and don''t count on it being fast):

#include <stdlib.h>
#include <string.h>


Thanks a lot, I''ll try this.. however, what is the concept behind the
problem I''m having? I mean, why when I try to obtain a message digest of
a particular ''string'' message and particular ''string'' key the function
works (message digest is always the same), and it doesn''t when I try the
same with identical string key, but a different ''string'' message? The
only difference between those messages is that with the latter the hex
content is what is important to me.. I mean, instead of having:

char msgtest[]="what do ya want for nothing?";
char key[]="Jefe";

I have a char * whose hex content is what matters to me..

thanks,

FBM


Fernando Barsoba wrote:

Skarmander wrote:

Fernando Barsoba wrote:

Hi all,

I very much need your help here guys.. I''m working on a IPSec
implementation, and when almost finished, I found a considerable
problem. I''m sending a particular array + a key to a HMAC-SHA1
function. I did the tests with the following:

void icv_Calculation_test(char p_output[20]) {
char msgtest[]="what do ya want for nothing?";
char key[]="Jefe";
uint8_t outputsha[20];
int size_message, size_key;
size_message = strlen(msgtest);
size_key = strlen(key);
hmac_sha(key, size_key, msgtest, size_message, outputsha,
sizeof(outputsha));
strcpy(p_output, outputsha);
return;
}

And I got the expected result, as in test case #2 from RFC 2202:
0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79
<snip> For instance, when trying to obtain the HMAC result for test case #1
which has:

char msgtest[]="Hi There";
and the key is 0x0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B

<snip> I mean, why when I try to obtain a message digest of
a particular ''string'' message and particular ''string'' key the function
works (message digest is always the same), and it doesn''t when I try the
same with identical string key, but a different ''string'' message? The
only difference between those messages is that with the latter the hex
content is what is important to me.. I mean, instead of having:

char msgtest[]="what do ya want for nothing?";
char key[]="Jefe";

I have a char * whose hex content is what matters to me..



The SHA function (apparently) expects a key that is a sequence of bytes.
As it so happens, "Jefe" is a sequence of bytes: assuming your system
uses an ASCII-compatible character set, the sequence can be represented
in hexadecimal as 0x4A65666500.

This is why passing a string to the function "just works": a string is
already a sequence of bytes. In the second example (key = 0x0b0b0b...)
you want to pass an actual byte sequence represented as a string of
hexadecimal digits, not the string "0x0b0b0b...", which is something
completely different.

S.


这篇关于加密算法中的数据类型问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆