void des_ecb_encrypt(des_cblock *input, des_cblock *output, des_key_schedule ks, int enc) { register DES_LONG l; DES_LONG ll[2]; const unsigned char *in=&(*input)[0]; unsigned char *out = &(*output)[0]; c2l(in,l); ll[0]=l; c2l(in,l); ll[1]=l; des_encrypt1(ll,ks,enc); l=ll[0]; l2c(l,out); l=ll[1]; l2c(l,out); l=ll[0]=ll[1]=0; }
DES_LONG des_cbc_cksum(const unsigned char *in, des_cblock *output, long length, des_key_schedule schedule, const_des_cblock *ivec) { register DES_LONG tout0,tout1,tin0,tin1; register long l=length; DES_LONG tin[2]; unsigned char *out = &(*output)[0]; const unsigned char *iv = &(*ivec)[0]; c2l(iv,tout0); c2l(iv,tout1); for (; l>0; l-=8) { if (l >= 8) { c2l(in,tin0); c2l(in,tin1); } else c2ln(in,tin0,tin1,l); tin0^=tout0; tin[0]=tin0; tin1^=tout1; tin[1]=tin1; des_encrypt1((DES_LONG *)tin,schedule,DES_ENCRYPT); /* fix 15/10/91 eay - thanks to [email protected] */ tout0=tin[0]; tout1=tin[1]; } if (out != NULL) { l2c(tout0,out); l2c(tout1,out); } tout0=tin0=tin1=tin[0]=tin[1]=0; return(tout1); }
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) { register DES_LONG tin0,tin1; register DES_LONG tout0,tout1,xor0,xor1,m0,m1; register 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 { register 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 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; }
/** * Encrypts a plaintext string * @param plaintext - the plaintext string * @return - the encrypted ciphertext string */ string DES::encrypt(const string& plaintext) { //LOGIC: //1. Check to make sure that the block is exactly 8 characters (i.e. 64 bits) //2. Declare an array DES_LONG block[2]; //3. Use ctol() to convert the first 4 chars into long; store the result in block[0] //4. Use ctol() to convert the second 4 chars into long; store the resul in block[1] //5. Perform des_encrypt1 in order to encrypt the block using this->key (see sample codes for details) //6. Convert the first ciphertext long to 4 characters using ltoc() //7. Convert the second ciphertext long to 4 characters using ltoc() //8. Save the results in the resulting 8-byte string (e.g. bytes[8]) //9. Convert the string (e.g. bytes[8]) to a C++ string. //10.Return the C++ string string ptext = plaintext; size_t number_of_padding = 0; while (ptext.size() < 8) { ptext.append("0"); number_of_padding++; } // convert int to a character in ASCII char number_of_padding_char = '0' + number_of_padding; /** * put the number of padding at the end of padded plaintext block * pad only one zero may be a special case? * std::string.back() should not be used on the empty string * it's important to do the bound checking when dealing with end of string * we will remove the padding in the cipher.cpp */ if (number_of_padding > 0 && number_of_padding < 8) { size_t last_index = ptext.length() - 1; ptext.at(last_index) = number_of_padding_char; } DES_LONG block[2]; //Convert C++ string to c-string char cstr1[4]; char cstr2[4]; ptext.copy(cstr1, 4, 0); cstr1[4] = '\0'; ptext.copy(cstr2, 4, 4); cstr2[4] = '\0'; unsigned char ucstr1[4]; memset(ucstr1, 0, sizeof(ucstr1)); for (int i = 0; i < sizeof(cstr1); i++) { ucstr1[i] = cstr1[i]; } ucstr1[sizeof(cstr1)] = '\0'; unsigned char ucstr2[4]; memset(ucstr2, 0, sizeof(ucstr2)); for (int i = 0; i < sizeof(cstr2); i++) { ucstr2[i] = cstr2[i]; } ucstr2[sizeof(cstr2)] = '\0'; //Convert first 4 chars into Long Int block[0] = ctol(ucstr1); block[1] = ctol(ucstr2); //Encrypt des_encrypt1(block,key,ENC); //Convert long to c string unsigned char txtText1[4]; unsigned char txtText2[4]; ltoc(block[0], txtText1); ltoc(block[1], txtText2); //Convert c string to C++ string string convertcstr1 = ""; for (int i = 0; i < sizeof(txtText1); i++) { convertcstr1.push_back(txtText1[i]); } string convertcstr2 = ""; for (int i = 0; i < sizeof(txtText2); i++) { convertcstr2.push_back(txtText2[i]); } //cout << "ciphertext: " << convertcstr1 + convertcstr2 << endl; //cout << "decrypt test: " << decrypt(convertcstr1 + convertcstr2) << "|" << endl; return convertcstr1 + convertcstr2; }
/** * Decrypts a string of ciphertext * @param ciphertext - the ciphertext * @return - the plaintext */ string DES::decrypt(const string& ciphertext) { //LOGIC: // Same logic as encrypt(), except in step 5. decrypt instead of encrypting DES_LONG block[2]; //Convert C++ string to c-string /*const char* cstrText1 = ciphertext.substr(0,4).c_str(); const char* cstrText2 = ciphertext.substr(4,4).c_str(); char cstr1[4], cstr2[4]; strncpy (cstr1, cstrText1, sizeof(cstrText1)); strncpy (cstr2, cstrText2, sizeof(cstrText2)); */ char cstr1[4]; char cstr2[4]; ciphertext.copy(cstr1, 4, 0); cstr1[4] = '\0'; ciphertext.copy(cstr2, 4, 4); cstr2[4] = '\0'; unsigned char ucstr1[4]; memset(ucstr1, 0, sizeof(ucstr1)); for (int i = 0; i < sizeof(cstr1); i++) { ucstr1[i] = cstr1[i]; } ucstr1[sizeof(cstr1)] = '\0'; unsigned char ucstr2[4]; memset(ucstr2, 0, sizeof(ucstr2)); for (int i = 0; i < sizeof(cstr2); i++) { ucstr2[i] = cstr2[i]; } ucstr2[sizeof(cstr2)] = '\0'; //Convert first 4 chars into Long Int block[0] = ctol(ucstr1); block[1] = ctol(ucstr2); //Decrypt des_encrypt1(block,key,DEC); //Convert Long back to c string unsigned char txtText1[4]; unsigned char txtText2[4]; ltoc(block[0], txtText1); ltoc(block[1], txtText2); //Convert c string to C++ string string convertcstr1 = ""; for (int i = 0; i < sizeof(txtText1); i++) { convertcstr1.push_back(txtText1[i]); } string convertcstr2 = ""; for (int i = 0; i < sizeof(txtText2); i++) { convertcstr2.push_back(txtText2[i]); } //cout << "length of plaintext: " << test.length() << endl; return convertcstr1 + convertcstr2; }