📄 p1363.c
字号:
unsigned char ch;
for (i=0;i<w->len;i++)
{
ch=w->val[i];
printf("%02x",ch);
}
printf("\n");
}
P1363_API void OCTET_PRINT_STRING(octet *w)
{
int i;
unsigned char ch;
for (i=0;i<w->len;i++)
{
ch=w->val[i];
printf("%c",ch);
}
}
/* Kill an octet string - Zeroise it for security */
P1363_API void OCTET_KILL(octet *w)
{
int i;
for (i=0;i<w->max;i++) w->val[i]=0;
w->len=0;
w->max=0;
free(w->val);
}
/*** P1363 Auxiliary Functions ***/
/* Internal - All Purpose Hash function */
/* Input is taken from
1. octet p
2. pointer to 32-bit number n
3. octet x
4. file fp - opened by calling program
5. octet e
in this order.
Returns TRUE if x and/or fp are empty
*/
static BOOL hash(octet *p,int *n,octet *x,FILE *fp,octet *e,int hash_type,octet *w)
{
BOOL result=TRUE;
int i,hlen,ch,c[4];
sha256 sh32;
#ifdef mr_unsign64
sha512 sh64;
#endif
char hh[MAX_HASH_BYTES];
if (n!=NULL)
{
c[0]=(*n>>24)&0xff;
c[1]=(*n>>16)&0xff;
c[2]=(*n>>8)&0xff;
c[3]=(*n)&0xff;
}
hlen=hash_params(hash_type,NULL);
if (hlen==0)
{
OCTET_EMPTY(w);
return result;
}
switch (hash_type)
{
case SHA1:
shs_init(&sh32);
if (p!=NULL)
for (i=0;i<p->len;i++) shs_process(&sh32,p->val[i]);
if (n!=NULL)
for (i=0;i<4;i++) shs_process(&sh32,c[i]);
if (x!=NULL)
for (i=0;i<x->len;i++)
{ shs_process(&sh32,x->val[i]); result=FALSE; }
if (fp!=NULL)
while ((ch=fgetc(fp))!=EOF)
{ shs_process(&sh32,ch); result=FALSE;}
if (e!=NULL)
for (i=0;i<e->len;i++) shs_process(&sh32,e->val[i]);
shs_hash(&sh32,hh);
break;
case SHA256:
shs256_init(&sh32);
if (p!=NULL)
for (i=0;i<p->len;i++) shs256_process(&sh32,p->val[i]);
if (n!=NULL)
for (i=0;i<4;i++) shs256_process(&sh32,c[i]);
if (x!=NULL)
for (i=0;i<x->len;i++)
{ shs256_process(&sh32,x->val[i]); result=FALSE; }
if (fp!=NULL)
while ((ch=fgetc(fp))!=EOF)
{ shs256_process(&sh32,ch); result=FALSE; }
if (e!=NULL)
for (i=0;i<e->len;i++) shs256_process(&sh32,e->val[i]);
shs256_hash(&sh32,hh);
break;
#ifdef mr_unsign64
case SHA384:
shs384_init(&sh64);
if (p!=NULL)
for (i=0;i<p->len;i++) shs384_process(&sh64,p->val[i]);
if (n!=NULL)
for (i=0;i<4;i++) shs384_process(&sh64,c[i]);
if (x!=NULL)
for (i=0;i<x->len;i++)
{ shs384_process(&sh64,x->val[i]); result=FALSE; }
if (fp!=NULL)
while ((ch=fgetc(fp))!=EOF)
{ shs384_process(&sh64,ch); result=FALSE; }
if (e!=NULL)
for (i=0;i<e->len;i++) shs384_process(&sh64,e->val[i]);
shs384_hash(&sh64,hh);
break;
case SHA512:
shs512_init(&sh64);
if (p!=NULL)
for (i=0;i<p->len;i++) shs512_process(&sh64,p->val[i]);
if (n!=NULL)
for (i=0;i<4;i++) shs512_process(&sh64,c[i]);
if (x!=NULL)
for (i=0;i<x->len;i++)
{ shs512_process(&sh64,x->val[i]); result=FALSE; }
if (fp!=NULL)
while ((ch=fgetc(fp))!=EOF)
{ shs512_process(&sh64,ch); result=FALSE; }
if (e!=NULL)
for (i=0;i<e->len;i++) shs512_process(&sh64,e->val[i]);
shs512_hash(&sh64,hh);
break;
#endif
default:
OCTET_EMPTY(w);
return result;
}
OCTET_EMPTY(w);
OCTET_JOIN_BYTES(hh,hlen,w);
for (i=0;i<hlen;i++) hh[i]=0;
return result;
}
/* General Purpose hash function */
P1363_API void HASH(int hash_type,octet *x,octet *y)
{
hash(x,NULL,NULL,NULL,NULL,hash_type,y);
}
/* Initialise a Cryptographically Strong Random Number Generator from
an octet of raw random data */
P1363_API void CREATE_CSPRNG(csprng *RNG,octet *raw)
{
strong_init(RNG,raw->len,raw->val,0L);
}
P1363_API void KILL_CSPRNG(csprng *RNG)
{
strong_kill(RNG);
}
/* Mask Generation Function */
P1363_API void MGF1(octet *z,int olen,int hash_type,octet *mask)
{
octet h;
int counter,cthreshold;
int hlen;
hlen=hash_params(hash_type,NULL);
if (hlen==0) return;
OCTET_INIT(&h,hlen);
OCTET_EMPTY(mask);
cthreshold=MR_ROUNDUP(olen,hlen);
for (counter=0;counter<cthreshold;counter++)
{
hash(z,&counter,NULL,NULL,NULL,hash_type,&h);
if (mask->len+hlen>olen) OCTET_JOIN_BYTES(h.val,olen%hlen,mask);
else OCTET_JOIN_OCTET(&h,mask);
}
OCTET_KILL(&h);
}
/*** P1363 recommended Message Encoding Methods ***/
/* message encoding methods for signatures with Appendix */
P1363_API BOOL EMSA1(octet *x,FILE *fp,int bits,int hash_type,octet *w)
{ /* w is a bits-length representative of the *
* octet string message x (if x!=NULL) *
* or of the file fp (if fp!=NULL) *
* w must be initialised for at least 20 bytes */
unsigned char c1,c2;
int i,hlen;
hash(NULL,NULL,x,fp,NULL,hash_type,w);
hlen=hash_params(hash_type,NULL);
if (hlen==0) return FALSE;
if (bits<8*hlen)
{
for (i=hlen-1;i>bits/8;i--)
{ /* remove bytes off the end */
w->val[i]=0;
w->len--;
}
bits=bits%8;
if (bits!=0)
{
for (i=w->len-1;i>=0;i--)
{
c1=(unsigned char)w->val[i];
c1>>=(8-bits);
if (i>0)
{
c2=(unsigned char)w->val[i-1];
c2<<=bits;
c1|=c2;
}
w->val[i]=(char)c1;
}
}
}
return TRUE;
}
P1363_API BOOL EMSA2(octet *x,FILE *fp,int bits,int hash_type,octet *w)
{ /* w is a bits-length representative of the *
* octet string message x (if x!=NULL) *
* and/or of the file fp (if fp!=NULL) *
* w must be initialised for at least 1+bits/8 *
* bytes */
int lp,hlen;
char id,p1;
octet h;
BOOL zero;
hlen=hash_params(hash_type,NULL);
if (hlen==0 || ((bits+1)%8)!=0) return FALSE;
if (bits<8*hlen+31 || (x!=NULL && fp!=NULL)) return FALSE;
id=sha_id[hash_type];
OCTET_INIT(&h,hlen);
zero=hash(NULL,NULL,x,fp,NULL,hash_type,&h);
p1=0x4b;
if (!zero) p1=0x6b;
lp=((bits+1)/8)-hlen-4;
OCTET_EMPTY(w);
OCTET_JOIN_BYTE(p1,1,w);
OCTET_JOIN_BYTE(0xbb,lp,w);
OCTET_JOIN_BYTE(0xba,1,w);
OCTET_JOIN_OCTET(&h,w);
OCTET_JOIN_BYTE(id,1,w);
OCTET_JOIN_BYTE(0xcc,1,w);
OCTET_KILL(&h);
return TRUE;
}
P1363_API BOOL EMSA3(octet *x,FILE *fp,int bits,int hash_type,octet *w)
{ /* w is a bits-length representative of the *
* octet string message x (if x!=NULL) *
* or of the file fp (if fp!=NULL) *
* w must be initialised big enough to take *
* the result > hlen+hashIDlen+10 bytes */
int olen,hlen,hashIDlen;
unsigned char *idptr;
octet h;
hlen=hash_params(hash_type,NULL);
if (hlen==0) return FALSE;
switch (hash_type)
{
case SHA1:
hashIDlen=SHA160ID[0];
idptr=&SHA160ID[1];
break;
case SHA256:
hashIDlen=SHA256ID[0];
idptr=&SHA256ID[1];
break;
#ifdef mr_unsign64
case SHA384:
hashIDlen=SHA384ID[0];
idptr=&SHA384ID[1];
break;
case SHA512:
hashIDlen=SHA512ID[0];
idptr=&SHA512ID[1];
break;
#endif
default:
break;
}
olen=bits/8;
if (olen<hashIDlen+hlen+10 || (x!=NULL && fp!=NULL)) return FALSE;
OCTET_INIT(&h,hlen);
hash(NULL,NULL,x,fp,NULL,hash_type,&h);
OCTET_EMPTY(w);
OCTET_JOIN_BYTE(0x01,1,w);
OCTET_JOIN_BYTE(0xff,olen-hashIDlen-hlen-2,w);
OCTET_JOIN_BYTE(0x00,1,w);
OCTET_JOIN_BYTES(idptr,hashIDlen,w);
OCTET_JOIN_OCTET(&h,w);
OCTET_KILL(&h);
return TRUE;
}
/* message encoding methods for signatures with Recovery */
/* Hash function ID is a mess - see see D5.2.2.2 Note 1 ?? */
P1363_API BOOL EMSR1_DECODE(BOOL hash_id,int r1len,int r2len,octet *f,octet *m2,FILE *fp,int bits,int hash_type,octet *v,int m1len,octet *m1)
{ /* m2 can come from an OCTET or from a file.... */
int rlen,hlen,olen=bits/8;
long m2len;
BOOL result;
octet hh,h,r;
hlen=hash_params(hash_type,NULL);
if (hlen==0) return FALSE;
if (hash_id)
{
if (r1len>hlen+1 || r2len>hlen+1) return FALSE;
}
else
{
if (r1len>hlen || r2len>hlen) return FALSE;
}
if (fp==NULL)
{
if (m2!=NULL) m2len=m2->len;
else m2len=0;
}
else
{
if (m2!=NULL) return FALSE;
m2len=filelength(fp);
}
if (m2len==0) rlen=r1len;
else rlen=r2len;
if (bits<8*rlen) return FALSE;
if (m1len > olen-rlen) return FALSE;
OCTET_INIT(&r,rlen+m1len);
OCTET_COPY(f,&r);
if (!OCTET_PAD(&r,rlen+m1len))
{
OCTET_KILL(&r);
return FALSE;
}
OCTET_CHOP(&r,rlen,m1);
OCTET_INIT(&hh,16+m1len);
OCTET_INIT(&h,hlen+1);
OCTET_JOIN_LONG((long)m1len,8,&hh);
OCTET_JOIN_LONG(m2len,8,&hh);
OCTET_JOIN_OCTET(m1,&hh);
hash(&hh,NULL,m2,fp,v,hash_type,&h);
if (hash_id)
OCTET_JOIN_BYTE(sha_id[hash_type],1,&h);
OCTET_CHOP(&h,rlen,NULL);
result=OCTET_COMPARE(&h,&r);
OCTET_KILL(&r);
OCTET_KILL(&h);
OCTET_KILL(&hh);
return result;
}
P1363_API BOOL EMSR1_ENCODE(BOOL hash_id,int r1len,int r2len,octet *m1,octet *m2,FILE *fp,int bits,int hash_type,octet *v,octet *f)
{ /* m2 can come from an OCTET or from a file.... */
int m1len,rlen,hlen,olen=bits/8;
long m2len;
octet hh,h;
hlen=hash_params(hash_type,NULL);
if (hlen==0) return FALSE;
if (hash_id)
{
if (r1len!=hlen+1 || r2len!=hlen+1) return FALSE;
}
else
{
if (r1len>hlen || r2len>hlen) return FALSE;
}
m1len=m1->len;
if (fp==NULL)
{
if (m2!=NULL) m2len=m2->len;
else m2len=0;
}
else
{
if (m2!=NULL) return FALSE;
m2len=filelength(fp);
}
if (m2len==0) rlen=r1len;
else rlen=r2len;
if (bits<8*rlen) return FALSE;
if (m1len > olen-rlen) return FALSE;
OCTET_INIT(&hh,16+m1len);
OCTET_INIT(&h,hlen+1);
OCTET_JOIN_LONG((long)m1len,8,&hh);
OCTET_JOIN_LONG(m2len,8,&hh);
OCTET_JOIN_OCTET(m1,&hh);
hash(&hh,NULL,m2,fp,v,hash_type,&h);
if (hash_id)
OCTET_JOIN_BYTE(sha_id[hash_type],1,&h);
OCTET_CHOP(&h,rlen,NULL);
OCTET_EMPTY(f);
OCTET_JOIN_OCTET(&h,f);
OCTET_JOIN_OCTET(m1,f);
OCTET_KILL(&h);
OCTET_KILL(&hh);
return TRUE;
}
/* EMSR2 - p is key derivation parameters - NULL by default *
* sym=TRUE - use symmetric encryption
* sym=FALSE - use stream cipher
* assumes KDF2 and AES. */
P1363_API BOOL EMSR2_DECODE(int padlen,BOOL sym,int hash_type,octet *p,octet *c,octet *v,octet *m)
{
int i,len,clen;
octet t,k;
clen=c->len;
if (clen<padlen) return FALSE;
OCTET_INIT(&t,clen);
if (sym)
{
OCTET_INIT(&k,16);
if (!KDF2(v,p,16,hash_type,&k))
{
OCTET_KILL(&t);
OCTET_KILL(&k);
return FALSE;
}
if (!AES_CBC_IV0_DECRYPT(&k,c,NULL,&t,NULL))
{
OCTET_KILL(&t);
OCTET_KILL(&k);
return FALSE;
}
}
else
{
OCTET_INIT(&k,clen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -