📄 p1363.c
字号:
if (!KDF2(v,p,clen,hash_type,&k))
{
OCTET_KILL(&t);
OCTET_KILL(&k);
return FALSE;
}
OCTET_COPY(c,&t);
OCTET_XOR(&k,&t);
}
OCTET_KILL(&k);
len=t.val[0];
if (len!=padlen)
{
OCTET_KILL(&t);
return FALSE;
}
for (i=1;i<padlen;i++)
{
if (t.val[i]!=padlen || i>=t.len)
{
OCTET_KILL(&t);
return FALSE;
}
}
OCTET_CHOP(&t,padlen,m);
OCTET_KILL(&t);
return TRUE;
}
P1363_API BOOL EMSR2_ENCODE(int padlen,BOOL sym,int hash_type,octet *p,octet *m,octet *v,octet *c)
{
int mlen;
octet k,t;
if (padlen<1 || padlen>255) return FALSE;
mlen=m->len;
OCTET_INIT(&t,padlen+mlen);
OCTET_JOIN_BYTE(padlen,padlen,&t);
OCTET_JOIN_OCTET(m,&t);
if (sym)
{
OCTET_INIT(&k,16); /* AES Key */
if (!KDF2(v,p,16,hash_type,&k))
{
OCTET_KILL(&t);
OCTET_KILL(&k);
return FALSE;
}
if (!AES_CBC_IV0_ENCRYPT(&k,&t,NULL,c,NULL))
{
OCTET_KILL(&t);
OCTET_KILL(&k);
return FALSE;
}
}
else
{
OCTET_INIT(&k,padlen+mlen);
if (!KDF2(v,p,padlen+mlen,hash_type,&k))
{
OCTET_KILL(&t);
OCTET_KILL(&k);
return FALSE;
}
OCTET_XOR(&k,&t);
OCTET_COPY(&t,c);
}
OCTET_KILL(&t);
OCTET_KILL(&k);
return TRUE;
}
/* PSS Message Encoding */
P1363_API BOOL EMSA4_ENCODE(BOOL hash_id,int hash_type,int slen,csprng *RNG,int bits,octet *m,FILE *fp,octet *f)
{
return EMSR3_ENCODE(hash_id,hash_type,slen,RNG,bits,NULL,m,fp,f);
}
P1363_API BOOL EMSA4_DECODE(BOOL hash_id,int hash_type,int slen,int bits,octet *f,octet *m,FILE *fp)
{
return EMSR3_DECODE(hash_id,hash_type,slen,bits,f,m,fp,NULL);
}
/* PSS-R Message Encoding for signature with recovery */
P1363_API BOOL EMSR3_ENCODE(BOOL hash_id,int hash_type,int slen,csprng *RNG,int bits,octet *m1,octet *m2,FILE *fp,octet *f)
{
int m1len,hlen,u,olen,t,zbytes,dblen;
unsigned char mask;
octet h,salt,md,db;
u=1;
if (hash_id) u=2;
if (m1!=NULL) m1len=m1->len;
else m1len=0;
hlen=hash_params(hash_type,NULL);
if (hlen==0) return FALSE;
olen=MR_ROUNDUP(bits,8);
t=8*olen-bits;
mask=0xFF;
if (t>0) mask>>=t;
if (8*m1len>bits-8*slen-8*hlen-8*u-1) return FALSE;
OCTET_INIT(&h,hlen);
hash(NULL,NULL,m2,fp,NULL,hash_type,&h);
OCTET_INIT(&salt,slen);
OCTET_RAND(RNG,slen,&salt);
OCTET_INIT(&md,8+m1len+hlen+slen);
OCTET_JOIN_LONG(8*m1len,8,&md);
OCTET_JOIN_OCTET(m1,&md);
OCTET_JOIN_OCTET(&h,&md);
OCTET_JOIN_OCTET(&salt,&md);
hash(&md,NULL,NULL,NULL,NULL,hash_type,&h);
OCTET_KILL(&md);
zbytes=olen-m1len-slen-hlen-u;
OCTET_INIT(&db,zbytes+m1len+slen);
OCTET_JOIN_BYTE(0x00,zbytes-1,&db);
OCTET_JOIN_BYTE(0x01,1,&db);
OCTET_JOIN_OCTET(m1,&db);
OCTET_JOIN_OCTET(&salt,&db);
OCTET_KILL(&salt);
dblen=olen-hlen-u;
MGF1(&h,dblen,hash_type,f);
OCTET_XOR(&db,f);
f->val[0]&=mask;
OCTET_JOIN_OCTET(&h,f);
OCTET_KILL(&h);
OCTET_KILL(&db);
if (hash_id)
{
OCTET_JOIN_BYTE(sha_id[hash_type],1,f);
OCTET_JOIN_BYTE(0xcc,1,f);
}
else
OCTET_JOIN_BYTE(0xbc,1,f);
/* remove leading zeros
while (f->val[0]==0) OCTET_SHIFT_LEFT(f,1); */
return TRUE;
}
P1363_API BOOL EMSR3_DECODE(BOOL hash_id,int hash_type,int slen,int bits,octet *f,octet *m2,FILE *fp,octet *m1)
{
int k,t,u,hlen,dblen,m1len,olen;
octet salt,h2,h,db,md,dbmask;
unsigned char mask,ch;
BOOL result;
u=1;
if (hash_id) u=2;
hlen=hash_params(hash_type,NULL);
if (hlen==0) return FALSE;
if (bits<8*slen+8*hlen+8*u+1) return FALSE;
olen=MR_ROUNDUP(bits,8);
t=8*olen-bits;
mask=0xFF;
if (t>0) mask>>=t;
if (!OCTET_PAD(f,olen)) return FALSE;
if (hash_id)
{
if (f->val[olen-1]!=(char)0xcc) return FALSE;
if (f->val[olen-2]!=sha_id[hash_type]) return FALSE;
}
else
if (f->val[olen-1]!=(char)0xbc) return FALSE;
if (f->val[0]&(~mask)) return FALSE;
OCTET_INIT(&h2,hlen);
hash(NULL,NULL,m2,fp,NULL,hash_type,&h2);
OCTET_INIT(&db,olen);
OCTET_INIT(&h,hlen+2);
dblen=olen-hlen-u;
OCTET_COPY(f,&db);
OCTET_CHOP(&db,dblen,&h);
OCTET_CHOP(&h,hlen,NULL);
OCTET_INIT(&dbmask,dblen);
MGF1(&h,dblen,hash_type,&dbmask);
OCTET_XOR(&dbmask,&db);
OCTET_KILL(&dbmask);
db.val[0]&=mask;
OCTET_INIT(&salt,slen);
OCTET_CHOP(&db,dblen-slen,&salt);
k=0;
while (k<db.len)
{
ch=db.val[k];
if (ch!=0x00) break;
k++;
}
if (k==db.len || ch!=0x01)
{
OCTET_KILL(&salt);
OCTET_KILL(&h);
OCTET_KILL(&db);
OCTET_KILL(&h2);
return FALSE;
}
OCTET_SHIFT_LEFT(&db,k+1);
m1len=db.len;
OCTET_INIT(&md,8+m1len+hlen+slen);
OCTET_JOIN_LONG(8*m1len,8,&md);
OCTET_JOIN_OCTET(&db,&md);
OCTET_JOIN_OCTET(&h2,&md);
OCTET_JOIN_OCTET(&salt,&md);
OCTET_KILL(&salt);
hash(&md,NULL,NULL,NULL,NULL,hash_type,&h2);
OCTET_KILL(&md);
result=OCTET_COMPARE(&h,&h2);
OCTET_KILL(&h2);
OCTET_KILL(&h);
if (!result)
{
OCTET_KILL(&db);
return FALSE;
}
result=TRUE;
if (m1!=NULL) OCTET_COPY(&db,m1);
else if (db.len!=0) result=FALSE;
OCTET_KILL(&db);
return result;
}
/* OAEP Message Encoding for Encryption */
P1363_API BOOL EME1_ENCODE(octet *m,csprng *RNG,int bits,octet *p,int hash_type,octet *f)
{
int slen,olen=bits/8;
int mlen=m->len;
int hlen,seedlen;
octet dbmask,seed;
hlen=seedlen=hash_params(hash_type,NULL);
if (hlen==0 || mlen>olen-hlen-seedlen-1) return FALSE;
if (m==f) return FALSE; /* must be distinct octets */
hash(p,NULL,NULL,NULL,NULL,hash_type,f);
slen=olen-mlen-hlen-seedlen-1;
OCTET_JOIN_BYTE(0,slen,f);
OCTET_JOIN_BYTE(0x1,1,f);
OCTET_JOIN_OCTET(m,f);
OCTET_INIT(&dbmask,olen-seedlen);
OCTET_INIT(&seed,seedlen);
OCTET_RAND(RNG,seedlen,&seed);
MGF1(&seed,olen-seedlen,hash_type,&dbmask);
OCTET_XOR(f,&dbmask);
MGF1(&dbmask,seedlen,hash_type,f);
OCTET_XOR(&seed,f);
OCTET_JOIN_OCTET(&dbmask,f);
OCTET_KILL(&seed);
OCTET_KILL(&dbmask);
return TRUE;
}
/* OAEP Message Decoding for Decryption */
P1363_API BOOL EME1_DECODE(octet *f,int bits,octet *p,int hash_type,octet *m)
{
BOOL comp;
int i,k,olen=bits/8;
int hlen,seedlen;
octet dbmask,seed,chash;
int x,t;
seedlen=hlen=hash_params(hash_type,NULL);
if (hlen==0 || olen<seedlen+hlen+1) return FALSE;
if (!OCTET_PAD(f,olen+1)) return FALSE;
OCTET_INIT(&chash,hlen);
hash(p,NULL,NULL,NULL,NULL,hash_type,&chash);
OCTET_INIT(&dbmask,olen-seedlen);
OCTET_INIT(&seed,seedlen);
x=f->val[0];
for (i=seedlen;i<olen;i++)
dbmask.val[i-seedlen]=f->val[i+1];
dbmask.len=olen-seedlen;
MGF1(&dbmask,seedlen,hash_type,&seed);
for (i=0;i<seedlen;i++) seed.val[i]^=f->val[i+1];
MGF1(&seed,olen-seedlen,hash_type,m);
OCTET_XOR(m,&dbmask);
comp=OCTET_NCOMPARE(&chash,&dbmask,hlen);
OCTET_SHIFT_LEFT(&dbmask,hlen);
OCTET_KILL(&seed);
OCTET_KILL(&chash);
for (k=0;;k++)
{
if (k>=dbmask.len)
{
OCTET_KILL(&dbmask);
return FALSE;
}
if (dbmask.val[k]!=0) break;
}
t=dbmask.val[k];
if (!comp || x!=0 || t!=0x01)
{
OCTET_KILL(&dbmask);
return FALSE;
}
OCTET_SHIFT_LEFT(&dbmask,k+1);
OCTET_COPY(&dbmask,m);
OCTET_KILL(&dbmask);
return TRUE;
}
/*** P1363 Key Derivation Functions ***/
P1363_API void KDF1(octet *z,octet *p,int hash_type,octet *k)
{
hash(z,NULL,p,NULL,NULL,hash_type,k);
}
P1363_API BOOL KDF2(octet *z,octet *p,int olen,int hash_type,octet *k)
{
/* NOTE: the parameter olen is the length of the output k in bytes */
int counter,cthreshold;
int hlen;
octet h;
hlen=hash_params(hash_type,NULL);
if (hlen==0) return FALSE;
cthreshold=MR_ROUNDUP(olen,hlen);
OCTET_EMPTY(k);
OCTET_INIT(&h,hlen);
for (counter=1;counter<=cthreshold;counter++)
{
hash(z,&counter,p,NULL,NULL,hash_type,&h);
if (k->len+hlen>olen) OCTET_JOIN_BYTES(h.val,olen%hlen,k);
else OCTET_JOIN_OCTET(&h,k);
}
OCTET_KILL(&h);
return TRUE;
}
/*** P1363 Message Authentication codes ***/
P1363_API BOOL MAC1(octet *m,FILE *fp,octet *k,int olen,int hash_type,octet *tag)
{
/* Input is either from an octet m, or a file fp. *
* olen is requested output length in bytes. k is the key *
* The output is the calculated tag */
int hlen,b;
octet h,k0;
hlen=hash_params(hash_type,&b);
if (hlen==0 || k->len<hlen/2) return FALSE;
if (m!=NULL && fp!=NULL) return FALSE;
if (olen<4 || olen>hlen) return FALSE;
OCTET_INIT(&k0,b);
OCTET_INIT(&h,hlen);
if (k->len > b) hash(k,NULL,NULL,NULL,NULL,hash_type,&k0);
else OCTET_COPY(k,&k0);
OCTET_JOIN_BYTE(0,b-k->len,&k0);
OCTET_XOR_BYTE(&k0,0x36);
hash(&k0,NULL,m,fp,NULL,hash_type,&h);
OCTET_XOR_BYTE(&k0,0x6a); /* 0x6a = 0x36 ^ 0x5c */
hash(&k0,NULL,&h,NULL,NULL,hash_type,&h);
OCTET_EMPTY(tag);
OCTET_JOIN_BYTES(h.val,olen,tag);
OCTET_KILL(&h);
OCTET_KILL(&k0);
return TRUE;
}
P1363_API BOOL AES_CBC_IV0_DECRYPT(octet *k,octet *c,FILE *ifp,octet *m,FILE *ofp)
{
aes a;
int i,ipt,opt,ch;
char buff[16];
BOOL fin,bad;
int padlen;
ipt=opt=0;
if (m!=NULL)
{
if (ofp!=NULL) return FALSE;
OCTET_CLEAR(m);
}
if (c!=NULL)
{
if (ifp!=NULL) return FALSE;
if (c->len==0) return FALSE;
else ch=c->val[ipt++];
}
if (!aes_init(&a,MR_CBC,k->len,k->val,NULL)) return FALSE;
if (ifp!=NULL)
{
ch=fgetc(ifp);
if (ch==EOF) return FALSE;
}
fin=FALSE;
forever
{
for (i=0;i<16;i++)
{
if (c!=NULL)
{
buff[i]=ch;
if (ipt>=c->len) {fin=TRUE; break;}
else ch=c->val[ipt++];
}
if (ifp!=NULL)
{
buff[i]=ch;
if ((ch=fgetc(ifp))==EOF) {fin=TRUE; break;}
}
}
aes_decrypt(&a,buff);
if (fin) break;
for (i=0;i<16;i++)
{
if (m!=NULL) if (opt<m->max) m->val[opt++]=buff[i];
if (ofp!=NULL) fputc(buff[i],ofp);
}
}
aes_end(&a);
bad=FALSE;
padlen=buff[15];
if (i!=15 || padlen<1 || padlen>16) bad=TRUE;
if (padlen>=2 && padlen<=16)
for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=TRUE;
if (!bad) for (i=0;i<16-padlen;i++)
{
if (m!=NULL) if (opt<m->max) m->val[opt++]=buff[i];
if (ofp!=NULL) fputc(buff[i],ofp);
}
if (m!=NULL) m->len=opt;
if (bad) return FALSE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -