void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, long length, DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec, int enc) { DES_LONG d0, d1, v0, v1; unsigned long l = length, n = ((unsigned int)numbits + 7) / 8; int num = numbits, i; DES_LONG ti[2]; unsigned char *iv; unsigned char ovec[16]; if (num > 64) return; iv = &(*ivec)[0]; c2l(iv, v0); c2l(iv, v1); if (enc) { while (l >= n) { l -= n; ti[0] = v0; ti[1] = v1; DES_encrypt3(ti, ks1, ks2, ks3); c2ln(in, d0, d1, n); in += n; d0 ^= ti[0]; d1 ^= ti[1]; l2cn(d0, d1, out, n); out += n; /* * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under * gcc :-( */ if (num == 32) { v0 = v1; v1 = d0; } else if (num == 64) { v0 = d0; v1 = d1; } else { iv = &ovec[0]; l2c(v0, iv); l2c(v1, iv); l2c(d0, iv); l2c(d1, iv); /* shift ovec left most of the bits... */ memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0)); /* now the remaining bits */ if (num % 8 != 0) for (i = 0; i < 8; ++i) { ovec[i] <<= num % 8; ovec[i] |= ovec[i + 1] >> (8 - num % 8); } iv = &ovec[0]; c2l(iv, v0); c2l(iv, v1); } } } else { while (l >= n) {
/* The input and output are loaded in multiples of 8 bits. * What this means is that if you hame numbits=12 and length=2 * the first 12 bits will be retrieved from the first byte and half * the second. The second 12 bits will come from the 3rd and half the 4th * byte. */ void des_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, long length, des_key_schedule schedule, des_cblock *ivec, int enc) { register DES_LONG d0,d1,v0,v1,n=(numbits+7)/8; register DES_LONG mask0,mask1; register unsigned long l=length; register int num=numbits; DES_LONG ti[2]; unsigned char *iv; if (num > 64) return; if (num > 32) { mask0=0xffffffffL; if (num == 64) mask1=mask0; else mask1=(1L<<(num-32))-1; } else { if (num == 32) mask0=0xffffffffL; else mask0=(1L<<num)-1; mask1=0x00000000L; } iv = &(*ivec)[0]; c2l(iv,v0); c2l(iv,v1); if (enc) { while (l >= n) { l-=n; ti[0]=v0; ti[1]=v1; des_encrypt((DES_LONG *)ti,schedule,DES_ENCRYPT); c2ln(in,d0,d1,n); in+=n; d0=(d0^ti[0])&mask0; d1=(d1^ti[1])&mask1; l2cn(d0,d1,out,n); out+=n; /* 30-08-94 - eay - changed because l>>32 and * l<<32 are bad under gcc :-( */ if (num == 32) { v0=v1; v1=d0; } else if (num == 64) { v0=d0; v1=d1; } else if (num > 32) /* && num != 64 */ { v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffffL; v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffffL; } else /* num < 32 */ { v0=((v0>>num)|(v1<<(32-num)))&0xffffffffL; v1=((v1>>num)|(d0<<(32-num)))&0xffffffffL; } }
void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, long length, DES_key_schedule *schedule, DES_cblock *ivec, int enc) { register DES_LONG sin0, sin1, xor0, xor1, tout0, tout1; DES_LONG tin[2]; const unsigned char *in; unsigned char *out, *iv; in = input; out = output; iv = &(*ivec)[0]; if (enc) { c2l(iv, xor0); c2l(iv, xor1); for (; length > 0; length -= 8) { if (length >= 8) { c2l(in, sin0); c2l(in, sin1); } else c2ln(in, sin0, sin1, length); tin[0] = sin0 ^ xor0; tin[1] = sin1 ^ xor1; DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); tout0 = tin[0]; tout1 = tin[1]; xor0 = sin0 ^ tout0; xor1 = sin1 ^ tout1; l2c(tout0, out); l2c(tout1, out); } } else { c2l(iv, xor0); c2l(iv, xor1); for (; length > 0; length -= 8) { c2l(in, sin0); c2l(in, sin1); tin[0] = sin0; tin[1] = sin1; DES_encrypt1((DES_LONG *)tin, schedule, DES_DECRYPT); tout0 = tin[0] ^ xor0; tout1 = tin[1] ^ xor1; if (length >= 8) { l2c(tout0, out); l2c(tout1, out); } else l2cn(tout0, tout1, out, length); xor0 = tout0 ^ sin0; xor1 = tout1 ^ sin1; } } tin[0] = tin[1] = 0; sin0 = sin1 = xor0 = xor1 = tout0 = tout1 = 0; }
void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length, DES_key_schedule *_schedule, DES_cblock *ivec, int enc) #endif { register DES_LONG tin0,tin1; register DES_LONG tout0,tout1,xor0,xor1; register long l=length; DES_LONG tin[2]; unsigned char *iv; iv = &(*ivec)[0]; if (enc) { c2l(iv,tout0); c2l(iv,tout1); for (l-=8; l>=0; l-=8) { c2l(in,tin0); c2l(in,tin1); tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT); tout0=tin[0]; l2c(tout0,out); tout1=tin[1]; l2c(tout1,out); } if (l != -8) { c2ln(in,tin0,tin1,l+8); tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; DES_encrypt1((DES_LONG *)tin,_schedule,DES_ENCRYPT); tout0=tin[0]; l2c(tout0,out); tout1=tin[1]; l2c(tout1,out); } #ifndef CBC_ENC_C__DONT_UPDATE_IV iv = &(*ivec)[0]; l2c(tout0,iv); l2c(tout1,iv); #endif } else { c2l(iv,xor0); c2l(iv,xor1); for (l-=8; l>=0; l-=8) { c2l(in,tin0); tin[0]=tin0; c2l(in,tin1); tin[1]=tin1; DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT); tout0=tin[0]^xor0; tout1=tin[1]^xor1; l2c(tout0,out); l2c(tout1,out); xor0=tin0; xor1=tin1; } if (l != -8) { c2l(in,tin0); tin[0]=tin0; c2l(in,tin1); tin[1]=tin1; DES_encrypt1((DES_LONG *)tin,_schedule,DES_DECRYPT); tout0=tin[0]^xor0; tout1=tin[1]^xor1; l2cn(tout0,tout1,out,l+8); #ifndef CBC_ENC_C__DONT_UPDATE_IV xor0=tin0; xor1=tin1; #endif } #ifndef CBC_ENC_C__DONT_UPDATE_IV iv = &(*ivec)[0]; l2c(xor0,iv); l2c(xor1,iv); #endif } tin0=tin1=tout0=tout1=xor0=xor1=0; tin[0]=tin[1]=0; }
/* Until Aug 1 2003 this function did not correctly implement CFB-r, so it * will not be compatible with any encryption prior to that date. Ben. */ void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, long length, DES_key_schedule *schedule, DES_cblock *ivec, int enc) { register DES_LONG d0,d1,v0,v1; register unsigned long l=length; register int num=numbits/8,n=(numbits+7)/8,i,rem=numbits%8; DES_LONG ti[2]; unsigned char *iv; #ifndef L_ENDIAN unsigned char ovec[16]; #else unsigned int sh[4]; unsigned char *ovec=(unsigned char *)sh; /* I kind of count that compiler optimizes away this assertioni,*/ assert (sizeof(sh[0])==4); /* as this holds true for all, */ /* but 16-bit platforms... */ #endif if (numbits<=0 || numbits > 64) return; iv = &(*ivec)[0]; c2l(iv,v0); c2l(iv,v1); if (enc) { while (l >= (unsigned long)n) { l-=n; ti[0]=v0; ti[1]=v1; DES_encrypt1((DES_LONG *)ti,schedule,DES_ENCRYPT); c2ln(in,d0,d1,n); in+=n; d0^=ti[0]; d1^=ti[1]; l2cn(d0,d1,out,n); out+=n; /* 30-08-94 - eay - changed because l>>32 and * l<<32 are bad under gcc :-( */ if (numbits == 32) { v0=v1; v1=d0; } else if (numbits == 64) { v0=d0; v1=d1; } else { #ifndef L_ENDIAN iv=&ovec[0]; l2c(v0,iv); l2c(v1,iv); l2c(d0,iv); l2c(d1,iv); #else sh[0]=v0, sh[1]=v1, sh[2]=d0, sh[3]=d1; #endif if (rem==0) memmove(ovec,ovec+num,8); else for(i=0 ; i < 8 ; ++i) ovec[i]=ovec[i+num]<<rem | ovec[i+num+1]>>(8-rem); #ifdef L_ENDIAN v0=sh[0], v1=sh[1]; #else iv=&ovec[0]; c2l(iv,v0); c2l(iv,v1); #endif } } } else { while (l >= (unsigned long)n)
void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, long length, DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec, int enc) { register DES_LONG tin0, tin1; register DES_LONG tout0, tout1, xor0, xor1; register const unsigned char *in; unsigned char *out; register long l = length; DES_LONG tin[2]; unsigned char *iv; in = input; out = output; iv = &(*ivec)[0]; if (enc) { c2l(iv, tout0); c2l(iv, tout1); for (l -= 8; l >= 0; l -= 8) { c2l(in, tin0); c2l(in, tin1); tin0 ^= tout0; tin1 ^= tout1; tin[0] = tin0; tin[1] = tin1; DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); tout0 = tin[0]; tout1 = tin[1]; l2c(tout0, out); l2c(tout1, out); } if (l != -8) { c2ln(in, tin0, tin1, l + 8); tin0 ^= tout0; tin1 ^= tout1; tin[0] = tin0; tin[1] = tin1; DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); tout0 = tin[0]; tout1 = tin[1]; l2c(tout0, out); l2c(tout1, out); } iv = &(*ivec)[0]; l2c(tout0, iv); l2c(tout1, iv); } else { register DES_LONG t0, t1; c2l(iv, xor0); c2l(iv, xor1); for (l -= 8; l >= 0; l -= 8) { c2l(in, tin0); c2l(in, tin1); t0 = tin0; t1 = tin1; tin[0] = tin0; tin[1] = tin1; DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); tout0 = tin[0]; tout1 = tin[1]; tout0 ^= xor0; tout1 ^= xor1; l2c(tout0, out); l2c(tout1, out); xor0 = t0; xor1 = t1; } if (l != -8) { c2l(in, tin0); c2l(in, tin1); t0 = tin0; t1 = tin1; tin[0] = tin0; tin[1] = tin1; DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); tout0 = tin[0]; tout1 = tin[1]; tout0 ^= xor0; tout1 ^= xor1; l2cn(tout0, tout1, out, l + 8); xor0 = t0; xor1 = t1; } iv = &(*ivec)[0]; l2c(xor0, iv); l2c(xor1, iv); } tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; tin[0] = tin[1] = 0; }
void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out, long length, DES_key_schedule *schedule, DES_cblock *ivec, const_DES_cblock *inw, const_DES_cblock *outw, int enc) { register DES_LONG tin0,tin1; register DES_LONG tout0,tout1,xor0,xor1; register DES_LONG inW0,inW1,outW0,outW1; register const unsigned char *in2; register long l=length; DES_LONG tin[2]; unsigned char *iv; in2 = &(*inw)[0]; c2l(in2,inW0); c2l(in2,inW1); in2 = &(*outw)[0]; c2l(in2,outW0); c2l(in2,outW1); iv = &(*ivec)[0]; if (enc) { c2l(iv,tout0); c2l(iv,tout1); for (l-=8; l>=0; l-=8) { c2l(in,tin0); c2l(in,tin1); tin0^=tout0^inW0; tin[0]=tin0; tin1^=tout1^inW1; tin[1]=tin1; DES_encrypt1(tin,schedule,DES_ENCRYPT); tout0=tin[0]^outW0; l2c(tout0,out); tout1=tin[1]^outW1; l2c(tout1,out); } if (l != -8) { c2ln(in,tin0,tin1,l+8); tin0^=tout0^inW0; tin[0]=tin0; tin1^=tout1^inW1; tin[1]=tin1; DES_encrypt1(tin,schedule,DES_ENCRYPT); tout0=tin[0]^outW0; l2c(tout0,out); tout1=tin[1]^outW1; l2c(tout1,out); } iv = &(*ivec)[0]; l2c(tout0,iv); l2c(tout1,iv); } else { c2l(iv,xor0); c2l(iv,xor1); for (l-=8; l>0; l-=8) { c2l(in,tin0); tin[0]=tin0^outW0; c2l(in,tin1); tin[1]=tin1^outW1; DES_encrypt1(tin,schedule,DES_DECRYPT); tout0=tin[0]^xor0^inW0; tout1=tin[1]^xor1^inW1; l2c(tout0,out); l2c(tout1,out); xor0=tin0; xor1=tin1; } if (l != -8) { c2l(in,tin0); tin[0]=tin0^outW0; c2l(in,tin1); tin[1]=tin1^outW1; DES_encrypt1(tin,schedule,DES_DECRYPT); tout0=tin[0]^xor0^inW0; tout1=tin[1]^xor1^inW1; l2cn(tout0,tout1,out,l+8); xor0=tin0; xor1=tin1; } iv = &(*ivec)[0]; l2c(xor0,iv); l2c(xor1,iv); } tin0=tin1=tout0=tout1=xor0=xor1=0; inW0=inW1=outW0=outW1=0; tin[0]=tin[1]=0; }
void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, long length, DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec1, DES_cblock *ivec2, int enc) { DES_LONG tin0,tin1; DES_LONG tout0,tout1,xor0,xor1,m0,m1; long l=length; DES_LONG tin[2]; unsigned char *iv1,*iv2; iv1 = &(*ivec1)[0]; iv2 = &(*ivec2)[0]; if (enc) { c2l(iv1,m0); c2l(iv1,m1); c2l(iv2,tout0); c2l(iv2,tout1); for (l-=8; l>=-7; l-=8) { tin[0]=m0; tin[1]=m1; DES_encrypt1(tin,ks3,1); m0=tin[0]; m1=tin[1]; if(l < 0) { c2ln(in,tin0,tin1,l+8); } else { c2l(in,tin0); c2l(in,tin1); } tin0^=tout0; tin1^=tout1; tin[0]=tin0; tin[1]=tin1; DES_encrypt1(tin,ks1,1); tin[0]^=m0; tin[1]^=m1; DES_encrypt1(tin,ks2,0); tin[0]^=m0; tin[1]^=m1; DES_encrypt1(tin,ks1,1); tout0=tin[0]; tout1=tin[1]; l2c(tout0,out); l2c(tout1,out); } iv1=&(*ivec1)[0]; l2c(m0,iv1); l2c(m1,iv1); iv2=&(*ivec2)[0]; l2c(tout0,iv2); l2c(tout1,iv2); } else { DES_LONG t0,t1; c2l(iv1,m0); c2l(iv1,m1); c2l(iv2,xor0); c2l(iv2,xor1); for (l-=8; l>=-7; l-=8) { tin[0]=m0; tin[1]=m1; DES_encrypt1(tin,ks3,1); m0=tin[0]; m1=tin[1]; c2l(in,tin0); c2l(in,tin1); t0=tin0; t1=tin1; tin[0]=tin0; tin[1]=tin1; DES_encrypt1(tin,ks1,0); tin[0]^=m0; tin[1]^=m1; DES_encrypt1(tin,ks2,1); tin[0]^=m0; tin[1]^=m1; DES_encrypt1(tin,ks1,0); tout0=tin[0]; tout1=tin[1]; tout0^=xor0; tout1^=xor1; if(l < 0) { l2cn(tout0,tout1,out,l+8); } else { l2c(tout0,out); l2c(tout1,out); } xor0=t0; xor1=t1; } iv1=&(*ivec1)[0]; l2c(m0,iv1); l2c(m1,iv1); iv2=&(*ivec2)[0]; l2c(xor0,iv2); l2c(xor1,iv2); } tin0=tin1=tout0=tout1=xor0=xor1=0; tin[0]=tin[1]=0; }
void RC2_cbc_encrypt(unsigned char *in, unsigned char *out, long length, RC2_KEY *ks, unsigned char *iv, int encrypt) { register unsigned long tin0,tin1; register unsigned long tout0,tout1,xor0,xor1; register long l=length; unsigned long tin[2]; if (encrypt) { c2l(iv,tout0); c2l(iv,tout1); iv-=8; for (l-=8; l>=0; l-=8) { c2l(in,tin0); c2l(in,tin1); tin0^=tout0; tin1^=tout1; tin[0]=tin0; tin[1]=tin1; RC2_encrypt(tin,ks); tout0=tin[0]; l2c(tout0,out); tout1=tin[1]; l2c(tout1,out); } if (l != -8) { c2ln(in,tin0,tin1,l+8); tin0^=tout0; tin1^=tout1; tin[0]=tin0; tin[1]=tin1; RC2_encrypt(tin,ks); tout0=tin[0]; l2c(tout0,out); tout1=tin[1]; l2c(tout1,out); } l2c(tout0,iv); l2c(tout1,iv); } else { c2l(iv,xor0); c2l(iv,xor1); iv-=8; for (l-=8; l>=0; l-=8) { c2l(in,tin0); tin[0]=tin0; c2l(in,tin1); tin[1]=tin1; RC2_decrypt(tin,ks); tout0=tin[0]^xor0; tout1=tin[1]^xor1; l2c(tout0,out); l2c(tout1,out); xor0=tin0; xor1=tin1; } if (l != -8) { c2l(in,tin0); tin[0]=tin0; c2l(in,tin1); tin[1]=tin1; RC2_decrypt(tin,ks); tout0=tin[0]^xor0; tout1=tin[1]^xor1; l2cn(tout0,tout1,out,l+8); xor0=tin0; xor1=tin1; } l2c(xor0,iv); l2c(xor1,iv); } tin0=tin1=tout0=tout1=xor0=xor1=0; tin[0]=tin[1]=0; }
void des_ncbc_encrypt(const unsigned char *in, unsigned char *out, long length, des_key_schedule schedule, des_cblock *ivec, int enc) { register DES_LONG tin0,tin1; register DES_LONG tout0,tout1,xor0,xor1; register long l=length; DES_LONG tin[2]; unsigned char *iv; iv = &(*ivec)[0]; if (enc) { c2l(iv,tout0); c2l(iv,tout1); for (l-=8; l>=0; l-=8) { c2l(in,tin0); c2l(in,tin1); tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; des_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT); tout0=tin[0]; l2c(tout0,out); tout1=tin[1]; l2c(tout1,out); } if (l != -8) { c2ln(in,tin0,tin1,l+8); tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; des_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT); tout0=tin[0]; l2c(tout0,out); tout1=tin[1]; l2c(tout1,out); } iv = &(*ivec)[0]; l2c(tout0,iv); l2c(tout1,iv); } else { c2l(iv,xor0); c2l(iv,xor1); for (l-=8; l>=0; l-=8) { c2l(in,tin0); tin[0]=tin0; c2l(in,tin1); tin[1]=tin1; des_encrypt1((DES_LONG *)tin,schedule,DES_DECRYPT); tout0=tin[0]^xor0; tout1=tin[1]^xor1; l2c(tout0,out); l2c(tout1,out); xor0=tin0; xor1=tin1; } if (l != -8) { c2l(in,tin0); tin[0]=tin0; c2l(in,tin1); tin[1]=tin1; des_encrypt1((DES_LONG *)tin,schedule,DES_DECRYPT); tout0=tin[0]^xor0; tout1=tin[1]^xor1; l2cn(tout0,tout1,out,l+8); xor0=tin0; xor1=tin1; } iv = &(*ivec)[0]; l2c(xor0,iv); l2c(xor1,iv); } tin0=tin1=tout0=tout1=xor0=xor1=0; tin[0]=tin[1]=0; }